8

I'm splitting a large shapefile into many smaller ones using ogr. I'd like to just copy all of the field and layer config information from the original. Here's how I'm doing it now:

src = ogr.Open('original.shp', 0)
layer = src.GetLayerByIndex(0)
driver = ogr.GetDriverByName('ESRI Shapefile')
ds = driver.CreateDataSource('file1.shp')
dest_layer = ds.CreateLayer('layer1',
                            srs = layer.GetSpatialRef(),
                            geom_type=layer.GetLayerDefn().GetGeomType())
feature  = layer.GetFeature(0)
[dest_layer.CreateField(feature.GetFieldDefnRef(i)) for i in range(feature.GetFieldCount())]

Is there a more succinct way to do this?

10

Use Fiona of Sean Gillies , a very simple wrapper of the OGR library (The Fiona User Manual)

All the elements of a shapefile (schema, records) are processed using Python dictionaries:

schema of one of my shapefiles as example:

{'geometry': 'LineString', 'properties': {u'faille': 'str:20', u'type': 'str:20', u'id': 'int'}}

one record in the shapefile:

{'geometry': {'type': 'LineString', 'coordinates': [(269884.20917418826, 151805.1917153612), (270409.89083992655, 153146.21637285672), (272298.05355768028, 154047.38494269375), (272941.74539327814, 155484.96337552898), (272169.31519056071, 156117.92701386689)]}, 'id': '1', 'properties': {'faille': u'de Salinas', 'type': u'normale'}}

so to duplicate a shapefile:

from shapely.geometry import mapping, shape
import fiona
# Read the original Shapefile
with fiona.collection('original.shp', 'r') as input:
    # The output has the same schema
    schema = input.schema.copy()
    # write a new shapefile
    with fiona.collection(''file1.shp', 'w', 'ESRI Shapefile', schema) as output:
        for elem in input:
             output.write({'properties': elem['properties'],'geometry': mapping(shape(elem['geometry']))})

If you want to split a large shapefile into many smaller ones, everything takes place in the for loop but all the schemas of the original shapefile are preserved in the dictionary with schema = input.schema.copy() and {'properties': elem['properties']

see How do I find vector line bearing in QGIS or GRASS? for an example of

  1. spliting a shapefile
  2. preserve the attributes of the original shapefile in the splitted shapefile
  3. and add a new field in the splitted shapefile

For Mac OS X or Linux users, it is easy to install. For Windows users, use the version of Christoph Gohlke Unofficial Windows Binaries for Python Extension Packages

  • Liked Fiona's simplicity a lot. But I ran into the problem that Fiona 1.6 does not work with GDAL 2. Hopefully they'll be upgrading that... – Akhorus Apr 25 '16 at 0:57
0

For those who struggle to install the libraries above:

import shapefile

r = shapefile.Reader('original') # original shp file
w = shapefile.Writer()

w.fields = list(r.fields)
w._shapes.extend(r.shapes()) # copy over geometry without any changes
w.save('new_shp_file')

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.