GDAL kullanarak şekil dosyalarının alan adlarını alma


15

Şekil dosyasını almak için Python'da GDAL kullanıyorum. Dosya için alan adlarını bilmek istiyorum, şu anki yolum:

fields = []
for i in range(1, layer.GetFeature(0).GetFieldCount()):
    field = layer.GetFeature(0).GetDefnRef().GetFieldDefn(i).GetName()
    fields.append(field)

Ama bu şekilde, ilk katmanın özelliğini alıyorum. Farklı katmanların farklı özelliklere sahip olabileceği anlamına mı geliyor?

Değilse, bu derinliğe girmek yerine alan adlarını bir kerede almak mümkün mü? Evetse, alan adlarını almanın daha kolay bir yolu var mı?


Shapefile her zaman yalnızca bir katmana sahiptir. Ayrıca her özelliğin aynı özelliklere sahip olduğuna inanıyorum, bu yüzden sadece ilk özelliği kontrol etmek yeterlidir.
user30184

Yanıtlar:


24

1) bireysel şekil dosyası: açıklamada olduğu gibi, şekil dosyasının yalnızca bir katmanı vardır. Yalnızca alanların adlarını istiyorsanız

from osgeo import ogr
source = ogr.Open("a_shapefile.shp")
layer = source.GetLayer()
schema = []
ldefn = layer.GetLayerDefn()
for n in range(ldefn.GetFieldCount()):
    fdefn = ldefn.GetFieldDefn(n)
    schema.append(fdefn.name)
print schema
['dip_dir', 'dip', 'cosa', 'sina']

GeoJSON formatını bir Python oluşturucu ile kullanabilirsiniz ( ogr_geointerface.py )

def records(layer):  
    # generator 
    for i in range(layer.GetFeatureCount()):
        feature = layer.GetFeature(i)
        yield json.loads(feature.ExportToJson())
features = record(layer)
first_feat = features.next()
print first_feat
{u'geometry': {u'type': u'Point', u'coordinates': [272070.600041, 155389.38792]}, u'type': u'Feature', u'properties': {u'dip_dir': 130, u'dip': 30, u'cosa': -0.6428, u'sina': -0.6428}, u'id': 0}
print first_feat['properties'].keys()
[u'dip', u'dip_dir', u'cosa', u'sina']

Bu Fiona'yı tanıtır (OGR'nin bir başka Python sarıcısı, Python 2.7.x ve 3.x). Tüm sonuçlar Python sözlükleridir (GeoJSON formatı).

import fiona
shapes = fiona.open("a_shapefile.shp")
shapes.schema
{'geometry': 'Point', 'properties': OrderedDict([(u'dip_dir', 'int:3'), (u'dip', 'int:2'), (u'cosa', 'float:11.4'), (u'sina', 'float:11.4')])}
shapes.schema['properties'].keys()
[u'dip', u'dip_dir', u'cosa', u'sina']
# first feature
shapes.next()
{'geometry': {'type': 'Point', 'coordinates': (272070.600041, 155389.38792)}, 'type': 'Feature', 'id': '0', 'properties': OrderedDict([(u'dip_dir', 130), (u'dip', 30), (u'cosa', -0.6428), (u'sina', -0.6428)])}

Ve GeoPandas (Fiona + pandalar , Python 2.7.x ve 3.x). Sonuç bir Pandas DataFrame (= GeoDataFrame) olur.

import geopandas as gpd
shapes = gpd.read_file("a_shapefile.shp")
list(shapes.columns.values)
[u'dip', u'dip_dir', u'cosa', u'sina', 'geometry']
# first features
shapes.head(3)

resim açıklamasını buraya girin

2) Birden çok şekil dosyası: bir klasördeki birden çok şekil dosyası arasında yineleme yapmak istiyorsanız

Osgeo.ogr ile

for subdir, dirs, files in os.walk(rootdir):
     for file in files:
        if file.endswith(".shp"):
           source = ogr.Open(os.path.join(rootdir, file))
           layer = source.GetLayer()
           ldefn = layer.GetLayerDefn()
           schema = [ldefn.GetFieldDefn(n).name  for n in range(ldefn.GetFieldCount())]
           print schema

veya bir jeneratör ile

def records(shapefile):  
    # generator 
    reader = ogr.Open(shapefile)
    layer = reader.GetLayer(0)
    for i in range(layer.GetFeatureCount()):
        feature = layer.GetFeature(i)
        yield json.loads(feature.ExportToJson())

for subdir, dirs, files in os.walk(rootdir):
    for file in files:
       if file.endswith(".shp"):
          layer = records(os.path.join(rootdir, file))
          print layer.next()['properties'].keys()

Fiona ile

import fiona
for subdir, dirs, files in os.walk(rootdir):
   for file in files:
      if file.endswith(".shp"):
          layer = fiona.open(os.path.join(rootdir, file))
          print layer.schema['properties'].keys()

1
Bu mükemmel bir cevap!
Kersten

11

kullanın:

from osgeo import ogr

ds = ogr.Open("file.shp")
lyr = ds.GetLayer()

field_names = [field.name for field in lyr.schema]
print(field_names)

Mükemmel. Hepsi bu kadar
Ishan Tomar
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.