6

I am working with GDAL and modify ESRI shapefiles with it. I am searching a possibility how to find all distince values from a single column of an attribute table with GDAL (Python). In SQL it would be SELECT DISTINCT field FROM table. I found how to do that in ArcPy but i prefer to use open source software.

Furthermore, i was thinking about iterating through the column (which are different classes) and calculate their area. Anybody an idea?

for i in range(layer.GetFeatureCount()):
  feature = layer.GetFeature(i)
  #here somehow iterate/sort through "feature.GetField("classes")"
9

You can use ExecuteSQL on an OGR data source to return a new layer. E.g.

from osgeo import ogr
ogr_ds = ogr.Open('table.shp')
sql = 'SELECT DISTINCT field FROM table'
layer = ogr_ds.ExecuteSQL(sql)
for i, feature in enumerate(layer):
    print('{0}: {1}'.format(i, feature.GetField(0)))

Note that there is no geometry in the layer, since it wasn't part of the SQL query.

Much more information for the default "OGRSQL" dialect is described here. An alternative SQLite SQL dialect can be enabled by using ogr_ds.ExecuteSQL(sql, dialect='SQLITE').

  • How the selection between OGR SQL and SQLite SQL dialects is done with python? Both dialects have some features which are missing from the other. – user30184 Sep 24 '14 at 22:01
5

With the SQLite dialect GDAL/OGR supports everything that is supported by SQLite http://www.sqlite.org/lang.html and Spatialite http://www.gaia-gis.it/gaia-sins/spatialite-sql-latest.html.

You can demonstrate how to get an ordered list of distinct attribute values with ogrinfo. For sure the same functionality is available also from python.

ogrinfo test.shp -dialect sqlite -sql "select distinct attribute_1 from test order by attribute_1"
INFO: Open of 'test.shp'
      using driver `ESRI Shapefile' successful.

Layer name: SELECT
Geometry: None
Feature Count: 342
Layer SRS WKT:
(unknown)
attribute_1: String (0.0)
OGRFeature(SELECT):0
  attribute_1 (String) = abc

OGRFeature(SELECT):1
  attribute_1 (String) = bca

OGRFeature(SELECT):2
  attribute_1 (String) = cba

Similarly you can get the sum of feature areas grouped by classes with

ogrinfo test.shp -dialect sqlite -sql "select attr_1, sum(area(geometry)) from test group by attr_1 order by attr_1"
  • Thanks for the answer but i search something in Python as mentioned. – g07kore Sep 24 '14 at 21:42
  • 1
    Sorry, I don't know python. Take this as encouragement, you can do it by calling SQL from python. – user30184 Sep 24 '14 at 21:48
5

I like Mike Ts response (+1!).

However, if you want to stick with what you have and not use sql, here's another way:

feature = layer.GetNextFeature()
field_vals = []
while feature:
  field_vals.append(feature.GetFieldAsString('FIELD_NAME'))
  feature = layer.GetNextFeature()

#use set to get distinct field_vals
print set(field_vals)

note that 'GetFieldAsString' may not be what you wish to use.

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.