Skip to content

Instantly share code, notes, and snippets.

@Jwely
Created September 4, 2015 19:58
Show Gist options
  • Save Jwely/7715460a71b73c51f8ee to your computer and use it in GitHub Desktop.
Save Jwely/7715460a71b73c51f8ee to your computer and use it in GitHub Desktop.
import ogr
__author__ = 'Jwely'
class Shape:
"""
Helps read data from shapefiles with ogr
"""
def __init__(self, shapefile_path, filter_list=None):
# set up object attributes and open
self.shapefile_path = shapefile_path # string
self.filter_list = filter_list # list of strings
# use ogr to build up field_names and layer object
shp = ogr.Open(shapefile_path)
layer = shp.GetLayer()
self.definition = layer.GetLayerDefn()
self.field_names = self._get_field_names(self.definition) # list
self.layer = self._filter_attributes(layer, filter_list) # ogr layer object
self.rows = self._make_rows(self.layer, self.field_names) # list of dicts
self.uniques = self._uniques(self.field_names, self.rows) # dict of lists for unique values
@staticmethod
def _get_field_names(definition):
"""
:param definition: an ogr definition instance
:return: a list of field names in this layer definition
"""
# get field names
field_names = [definition.GetFieldDefn(i).GetName() for
i in range(definition.GetFieldCount())]
return field_names
@staticmethod
def _filter_attributes(layer_object, filter_list):
"""
filters a layer instance by one or more criteria
:param layer_object: An ogr layer instance
:param filter_list: a list of filter strings, syntax is something like
"SUB_REGION = 'pacific'"
readmore at https://pcjericks.github.io/py-gdalogr-cookbook/vector_layers.html#filter-by-attribute
"""
if filter_list is not None:
if not isinstance(filter_list, list):
filter_list = [filter_list]
for filt in filter_list:
layer_object.SetAttributeFilter(filt)
return layer_object
@staticmethod
def _make_rows(layer, field_names):
# this will be filled with a dictionary structure for each row. keys = field_names
rows = []
for feature in layer:
this_row = {}
for field_name in field_names:
this_row[field_name] = feature.GetField(field_name)
rows.append(this_row)
print("Loaded {0} features".format(len(rows)))
return rows
@staticmethod
def _uniques(field_names, rows):
unique_values = {}
for field in field_names:
unique_values[field] = sorted(set([row[field] for row in rows]))
for key in unique_values:
print("{key} {num} {vals}".format(key=key.ljust(16),
num=str(len(unique_values[key])).ljust(5),
vals=unique_values[key]))
return unique_values
if __name__ == "__main__":
fpath = r"filepath to a shapefile"
s = Shape(fpath)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment