Tell me more ×
Geographic Information Systems Stack Exchange is a question and answer site for cartographers, geographers and GIS professionals. It's 100% free, no registration required.

Can someone demonstrate a simple way to write geometry data-structures from shapely into shapefiles? I am particularly interested in polygons with holes and linestrings. It would also be beneficial to stay away from arcpy (so osgeo, pyshp, etc. would all be better).

share|improve this question

2 Answers

up vote 5 down vote accepted

Well-known binary is a good binary exchange format that can be exchanged with plenty of GIS software, including Shapely and GDAL/OGR.

This is a tiny example of the workflow:

from osgeo import ogr
from shapely.geometry import Polygon

# Here's an example Shapely geometry
poly = Polygon([(0, 0), (0, 1), (1, 1), (0, 0)])

# Now convert it to a shapefile with OGR    
driver = ogr.GetDriverByName('Esri Shapefile')
ds = driver.CreateDataSource('my.shp')
layer = ds.CreateLayer('', None, ogr.wkbPolygon)
# Add one attribute
layer.CreateField(ogr.FieldDefn('id', ogr.OFTInteger))
defn = layer.GetLayerDefn()

## If there are multiple geometries, put the "for" loop here

# Create a new feature (attribute and geometry)
feat = ogr.Feature(defn)
feat.SetField('id', 123)

# Make a geometry, from Shapely object
geom = ogr.CreateGeometryFromWkb(poly.wkb)
feat.SetGeometry(geom)

layer.CreateFeature(feat)
feat = geom = None  # destroy these

# Save and close everything
ds = layer = feat = geom = None

Update: Although the poster has accepted the GDAL/OGR answer, here is a Fiona equivalent:

from shapely.geometry import mapping, Polygon
from fiona import collection

# Here's an example Shapely geometry
poly = Polygon([(0, 0), (0, 1), (1, 1), (0, 0)])

# Define a polygon feature geometry with one attribute
schema = {
    'geometry': 'Polygon',
    'properties': {'id': 'int'},
}

# Write a new Shapefile
with collection('my_shp2.shp', 'w', 'Esri Shapefile', schema) as c:
    ## If there are multiple geometries, put the "for" loop here
    feat = {}
    feat['geometry'] = mapping(poly)
    feat['properties'] = {'id': 123}
    c.write(feat)

(Note Windows users: you have no excuse)

share|improve this answer
Interested why you picked this method rather then the Fiona library. – Nathan W Feb 24 at 7:21
Well, the poster was looking for an osgeo.ogr example, and the comparison is interesting. – sgillies Feb 24 at 17:08
@sgillies explicit comparison added – Mike Toews Feb 24 at 18:33
2  
Well, to be honest it was mostly pragmatics. I appreciated the effort of demonstrating the code in response to my question and I was already mucking about with osgeo. I have since tried both methods and they are both sufficient answers. I appreciate the effort from the responders being both accurate and fast. – user1124683 Feb 24 at 22:06

I've designed Fiona to work well with Shapely. Here is a very simple example of using them together to "clean" shapefile features: https://github.com/Toblerity/Fiona/blob/master/examples/with-shapely.py.

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.