ArcMap lisansı olmadan Python kullanarak Shapefile içeriğine bakmak mümkün mü?


40

ArcMap lisansına sahip olmadan Python kullanarak bir şekil dosyasının içeriğine bakmak mümkün olup olmadığını merak ettim. Durum, yalnızca ESRI yazılımından değil, birçok farklı uygulamadan şekil dosyaları oluşturabilmenizdir. Uzamsal referansı, özellik türünü, özellik adlarını ve tanımlarını ve bir şekil dosyasındaki alanların içeriğini kontrol eden ve bunları bir kabul edilebilir değerler kümesiyle karşılaştıran bir Python betiği oluşturmak istiyorum. Kurumun ESRI lisansı olmasa bile bu betiğin çalışmasını istiyorum. Böyle bir şey yapmak için, ArcPy'yi kullanmak zorunda mısınız yoksa ArcPy'yi kullanmadan bir şekil dosyasına kazabilir misiniz?


1
Ne kadar çaba harcamak istediğinize bağlı .. yardımcı olacak birkaç açık kaynak kütüphanesi var (Aarons'un cevabına göre OGR'yi seviyorum) ama gerçekten kontrol etmek istiyorsanız (ve bunun için çalışmaya hazırsanız) (başlangıçta Esri tarafından yazılmış) açık bir formattır, bkz. en.wikipedia.org/wiki/Shapefile
Michael Stimson

1
Son (son birkaç yıl) ESRI şekil dosyaları yeni coğrafi veritabanı biçiminde gizlidir. ARCxxx yazılımı dışında hiçbir şey onları kıramaz gibi görünüyor. Birçok kamu kurumu kamuya açık bilgi için kullanıyor ... utanç verici.

Yanıtlar:


34

Hem vektör hem de raster verilerle çalışmak için Python GDAL / OGR API'sine aşina olmanızı tavsiye ederim . GDAL / OGR kullanmaya başlamanın en kolay yolu python (x, y) , Anaconda veya OSGeo4W gibi bir python dağılımıdır .

Özel görevleriniz için GDAL kullanımı hakkında daha fazla bilgi:

Ek olarak, USU'dan başlamak için aşağıdaki öğreticiyi tavsiye ederim.


Yukarıdaki örneklerden ödünç alarak, aşağıdaki komut dosyası aşağıdaki işlemleri gerçekleştirmek için FOSS araçlarını kullanır:

  1. Mekansal referansı kontrol edin
  2. Shapefile alanlarını ve türlerini alın
  3. Kullanıcı tanımlı bir alandaki satırların bir değer içerip içermediğini kontrol edin

# Import the necessary modules
from  osgeo import ogr, osr

driver = ogr.GetDriverByName('ESRI Shapefile')
shp = driver.Open(r'C:\your\shapefile.shp')

# Get Projection from layer
layer = shp.GetLayer()
spatialRef = layer.GetSpatialRef()
print spatialRef

# Get Shapefile Fields and Types
layerDefinition = layer.GetLayerDefn()

print "Name  -  Type  Width  Precision"
for i in range(layerDefinition.GetFieldCount()):
    fieldName =  layerDefinition.GetFieldDefn(i).GetName()
    fieldTypeCode = layerDefinition.GetFieldDefn(i).GetType()
    fieldType = layerDefinition.GetFieldDefn(i).GetFieldTypeName(fieldTypeCode)
    fieldWidth = layerDefinition.GetFieldDefn(i).GetWidth()
    GetPrecision = layerDefinition.GetFieldDefn(i).GetPrecision()
    print fieldName + " - " + fieldType+ " " + str(fieldWidth) + " " + str(GetPrecision)

# Check if rows in attribute table meet some condition
inFeature = layer.GetNextFeature()
while inFeature:

    # get the cover attribute for the input feature
    cover = inFeature.GetField('cover')

    # check to see if cover == grass
    if cover == 'trees':
        print "Do some action..."

    # destroy the input feature and get a new one
    inFeature = None
    inFeature = inLayer.GetNextFeature()


Bilgi @MikeT için teşekkürler. GDAL / OGR belgeleri yemek kitabı boyunca 'Destroy ()' yöntemini kullanır. Bu yöntemle ilgili hangi sorunları görüyorsunuz?
Aaron

1
Destroy () kullandığınızda segfaults oluşabileceği durumlar vardır ve bu yöntemi ciltlenmelerde ortaya çıkarmak bir tasarım hatasıydı. Daha iyi bir yöntem gibi GDAL nesnelerini serbest bırakmaktır inFeature = None. GDAL / OGR yemek kitabı GDAL / OGR çekirdek ekibinin bir parçası değildir veya yazmaz.
Mike T,

@MikeT Yorumunuzu içerecek şekilde yazıyı düzenledim - teşekkürler.
Aaron

31

Python'da ArcPy'den daha eski olan shapefile dosyalarını okuyacak pek çok modül vardır, Python Paket Dizinine (PyPi) bakınız: shapefiles . Ayrıca GIS SE'de birçok örnek vardır ( örneğin [Python] Fiona’yı arayın )

Hepsi geometriyi, alanları ve çıkıntıları okuyabilir.

Ancak PySAL gibi diğer modüller : Python Mekansal Analiz Kütüphanesi , Cartopy ( pyshp kullanan ) veya Matplotlib Basemap ayrıca diğer şeylerin yanı sıra shapefile de okuyabilir.

Kullanım için en kolay olan Fiona , ancak yalnızca ArcPy, kullanım biliyorsanız pyshp çünkü osgeo ve Fiona gerektirir GDAL C / C ++ kütüphanesi kurulabilir, GeoPandas ihtiyacı Pandalar modülü ve PySAL kadar büyük (diğer birçoklarının tedavileri)

Yalnızca bir şekil dosyasının içeriğini okumak istiyorsanız, karmaşık şeylere ihtiyacınız yoktur, ArcPy'de de ( ArcPy: AsShape ) uygulanan geo arabirim protokolünü (GeoJSON) kullanın.

Fiona ile (Python sözlükleri olarak):

import fiona
with fiona.open('a_shape.shp') as shp:
     # schema of the shapefile
     print shp.schema
     {'geometry': 'Point', 'properties': OrderedDict([(u'DIP', 'int:2'), (u'DIP_DIR', 'int:3'), (u'TYPE', 'str:10')])}
     # projection
     print shp.crs
     {u'lon_0': 4.367486666666666, u'ellps': u'intl', u'y_0': 5400088.438, u'no_defs': True, u'proj': u'lcc', u'x_0': 150000.013, u'units': u'm', u'lat_2': 49.8333339, u'lat_1': 51.16666723333333, u'lat_0': 90}
     for feature in shp:
        print feature              
{'geometry': {'type': 'Point', 'coordinates': (272070.600041, 155389.38792)}, 'type': 'Feature', 'id': '0', 'properties': OrderedDict([(u'DIP', 30), (u'DIP_DIR', 130), (u'TYPE', u'incl')])}
{'geometry': {'type': 'Point', 'coordinates': (271066.032148, 154475.631377)}, 'type': 'Feature', 'id': '1', 'properties': OrderedDict([(u'DIP', 55), (u'DIP_DIR', 145), (u'TYPE', u'incl')])}
{'geometry': {'type': 'Point', 'coordinates': (273481.498868, 153923.492988)}, 'type': 'Feature', 'id': '2', 'properties': OrderedDict([(u'DIP', 40), (u'DIP_DIR', 155), (u'TYPE', u'incl')])}

Pyshp ile (Python sözlükleri olarak)

import shapefile
reader= shapefile.Reader("a_shape.shp")
# schema of the shapefile
print dict((d[0],d[1:]) for d in reader.fields[1:])
{'DIP_DIR': ['N', 3, 0], 'DIP': ['N', 2, 0], 'TYPE': ['C', 10, 0]}
fields = [field[0] for field in reader.fields[1:]]
for feature in reader.shapeRecords():
    geom = feature.shape.__geo_interface__
    atr = dict(zip(fields, feature.record))
    print geom, atr
{'type': 'Point', 'coordinates': (272070.600041, 155389.38792)} {'DIP_DIR': 130, 'DIP': 30, 'TYPE': 'incl'}
{'type': 'Point', 'coordinates': (271066.032148, 154475.631377)} {'DIP_DIR': 145, 'DIP': 55, 'TYPE': 'incl'}
{'type': 'Point', 'coordinates': (273481.498868, 153923.492988)} {'DIP_DIR': 155, 'DIP': 40, 'TYPE': 'incl'}

Osgeo / ogr ile (Python sözlükleri olarak)

from osgeo import ogr
reader = ogr.Open("a_shape.shp")
layer = reader.GetLayer(0)
for i in range(layer.GetFeatureCount()):
    feature = layer.GetFeature(i)
    print feature.ExportToJson()
{"geometry": {"type": "Point", "coordinates": [272070.60004, 155389.38792]}, "type": "Feature", "properties": {"DIP_DIR": 130, "DIP": 30, "TYPE": "incl"}, "id": 0}
{"geometry": {"type": "Point", "coordinates": [271066.032148, 154475.631377]}, "type": "Feature", "properties": {"DIP_DIR": 145, "DIP": 55, "TYPE": "incl"}, "id": 1}
{"geometry": {"type": "Point", "coordinates": [273481.49887, 153923.492988]}, "type": "Feature", "properties": {"DIP_DIR": 155, "DIP": 40, "TYPE": "incl"}, "id": 2}

GeoPandas ile (Pandalar veri çerçevesi olarak)

import geopandas as gp
shp = gp.GeoDataFrame.from_file('a_shape.shp')
print shp
        DIP_DIR    DIP  TYPE                       geometry
0         130       30  incl          POINT (272070.600041 155389.38792)
1         145       55  incl          POINT (271066.032148 154475.631377)
2         155       40  incl          POINT (273481.498868 153923.492988)

* Jeopanda hakkında not Fiona ve GDAL'ın eski sürümlerini onunla birlikte kullanmak zorundasınız, yoksa kurulmayacak. GDAL: 1.11.2 Fiona: 1.6.0 Jeopandalar: 0.1.0.dev-

İnternette ve hatta kitaplarda birçok ders var ( Python Mekansal Gelişimi , Python ile Mekansal Analizi Öğrenme ve basında Python ile Geoprocessing )

Daha genel olarak, eğer ArcPy'siz Python kullanmak istiyorsanız, Python'u kullanarak shapefilenin basit tematik haritalamasına bakın.


Fiona'nın ana sayfasında diyor kiThe kinds of data in GIS are roughly divided into rasters representing continuous scalar fields (land surface temperature or elevation, for example) and vectors representing discrete entities like roads and administrative boundaries. Fiona is concerned exclusively with the latter
Mawg 21:16

2
Açıkçası, soru şekillendirme ve rasterler hakkında değil. Raster dosyalar için diğer modüllerdir.
gen,

Mükemmel cevap! 2017'de güncellenecek bir şey var mı?
Michael,

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.