[GIS] Error with Python Script using Shapely

fionapythonshapely

My professor gave us a basic Python script that demonstrated how Shapely works with a shapefile, however it's not working for me. Here is the code:

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

with collection("hawaii_vector_data.shp","r") as input:
  for polygon in input:
    c = polygon['properties']['class']
    if c == 0 or c == None:
      continue
    s = shape(polygon['geometry'])
    print s

and when I run it I get this Traceback error:

Traceback (most recent call last):
  File "test.py", line 6, in <module>
    c = polygon['properties']['class']
KeyError: 'class'

Since I am new to using Shapely I have no idea what the error might be. Any advice would be great.

Best Answer

Fiona uses dictionaries to read shapefiles

1) the keys of the dictionary = schema of the shapefile

shapes = fiona.open("polygons.shp")
# schema of the shapefile -> the keys of the dictionary
print shapes.schema
{'geometry': 'Polygon', 'properties': OrderedDict([(u'id', 'int:10')])}
# read first feature of the shapefile
first = shapes.next()
print first
{'geometry': {'type': 'Polygon', 'coordinates': [[(151116.87238259654, 135890.8706318218), (153492.19971554304, 134793.3055883224), (153934.50204650551, 133892.31935858406), (152623.97662143156, 131811.86024627919), (150903.91200102202, 130894.49244872745), (149347.66305874675, 132991.33312884573), (149151.08424498566, 134383.76639298678), (151116.87238259654, 135890.8706318218)]]}, 'type': 'Feature', 'id': '0', 'properties': OrderedDict([(u'id', 2)])}

2) the geometry key

print first['geometry'] # GeoJSON format
{'type': 'Polygon', 'coordinates': [[(151116.87238259654, 135890.8706318218), (153492.19971554304, 134793.3055883224), (153934.50204650551, 133892.31935858406), (152623.97662143156, 131811.86024627919), (150903.91200102202, 130894.49244872745), (149347.66305874675, 132991.33312884573), (149151.08424498566, 134383.76639298678), (151116.87238259654, 135890.8706318218)]]}
# the coordinates of the geometry
print ['geometry']["coordinates"]
[[(151116.87238259654, 135890.8706318218), (153492.19971554304, 134793.3055883224), (153934.50204650551, 133892.31935858406), (152623.97662143156, 131811.86024627919), (150903.91200102202, 130894.49244872745), (149347.66305874675, 132991.33312884573), (149151.08424498566, 134383.76639298678), (151116.87238259654, 135890.8706318218)]]

If you want to transform the geometry to a Shapely geometry

poly = shape(first['geometry']
print poly
POLYGON ((151116.8723825965 135890.8706318218, 153492.199715543 134793.3055883224, 153934.5020465055 133892.3193585841, 152623.9766214316 131811.8602462792, 150903.912001022 130894.4924487275, 149347.6630587468 132991.3331288457, 149151.0842449857 134383.7663929868, 151116.8723825965 135890.8706318218))

3) the attributes -> property key

print first['property']
OrderedDict([(u'id', 2)])
# value of attribute id
print fist['properties']['id']
2

4) you problem

with fiona.open("polygons.shp") as input:
    for polygon in input:
        c = polygon['properties']['id']
        s = shape(polygon['geometry'])
        print c, s
....

And you can see that the error in your script comes from the fact that there is no "class" key in the properties of your shapefile.

If you want to select some features:

with fiona.open("polygons.shp") as input:
    for polygon in input:
        if polygon['properties']['id'] > 0:
             s = shape(polygon['geometry'])
             print c, s
Related Question