[GIS] Deleting shapefile element using Fiona

fionageometrygeoprocessingpythonshapefile

I have downloaded a shapefile (.shp) that I'd like to read in using fiona.open and delete records. The reason I'd like to delete records is that some records have "None" geometries.

So I want to delete a record if it doesn't have a geometry: {'geometry': None, 'type': 'Feature', 'id': etc etc etc}

Here's my code:

import fiona
with fiona.open('data/ssc_2016_aust_shape/SSC_2016_AUST.shp') as file:
    for p in file: # for every record - note that p is a dictionary 
        if p["geometry"] is None: # if p doesn't have a geometry
            del p # then delete the entire record in the shape file 

I'd like for the original shapefile (.shp) to be overwritten (this is important).

You can download the shapefile here: http://www.abs.gov.au/AUSSTATS/abs@.nsf/DetailsPage/1270.0.55.003July%202016?OpenDocument

The file on the ABS website is called "State Suburbs ASGS Ed 2016 Digital Boundaries in ESRI Shapefile Format" in the form of a ZIP file.

Best Answer

You can't, directly. See the fiona user manual:

1.6 Writing Vector Data

A vector file can be opened for writing in mode 'a' (append) or mode 'w' (write).

Note:

The in situ “update” mode of OGR is quite format dependent and is therefore not supported by Fiona.

...

You could copy the valid records to a temporary dataset (see Writing New Files) and then copy it over the original, or you could just operate on the valid records only (see filtering topic - Slicing and masking iterators).

For example (based on the fiona user manual):

#Note completely untested...

with fiona.open(inshp) as source, fiona.open(outshp, 'w',
                                             driver=source.driver,
                                             crs=source.crs,
                                             schema=source.schema) as dest:
    for feat in source:
        if feat["geometry"] is not None:
            dest.write(feat)