Чи можливо переглянути вміст Shapefile за допомогою Python без ліцензії ArcMap?


40

Мені було цікаво, чи можна переглянути вміст файлу форми за допомогою Python без наявності ліцензії ArcMap. Ситуація полягає в тому, що ви можете створювати форм-файли з багатьох різних програм, не тільки з програмного забезпечення ESRI. Я хотів би створити сценарій Python, який перевіряє просторову посилання, тип функції, імена атрибутів та визначення, а також вміст полів у формі форми та порівнює їх із набором прийнятних значень. Я хотів би, щоб цей сценарій працював, навіть якщо організація не має ліцензій ESRI. Щоб зробити щось подібне, чи потрібно вам використовувати ArcPy чи ви можете викопати файл форми без використання ArcPy?


1
Це залежить від того, скільки зусиль ви хочете докласти до цього. Є кілька бібліотек з відкритим кодом, які допоможуть (мені подобається OGR відповідно до відповіді Аарона), але якщо ви дійсно хочете контролювати (і готові працювати на це) Shapefile (спочатку Esri) - це відкритий формат, див. en.wikipedia.org/wiki/Shapefile
Майкл Стімсон

1
Останні (останні кілька років) формуляри ESRI приховані у новому форматі бази даних геоданих. Здається, що нічого не може зламати їх, крім програмного забезпечення ARCxxx. Багато державних агентств використовують це для публічної інформації ... ганьба.

Відповіді:


34

Я рекомендую ознайомитись з API Python GDAL / OGR для роботи як з векторними, так і з растровими даними. Найпростіший спосіб почати використовувати GDAL / OGR - через розподілення пітона, такі як python (x, y) , Anaconda або OSGeo4W .

Детальніші відомості про використання GDAL для конкретних завдань:

Додатково я рекомендую наступний підручник від УСУ, щоб розпочати роботу.


Запозичившись із наведених вище прикладів, наступний скрипт використовує інструменти FOSS для виконання наступних дій:

  1. Перевірте просторову орієнтир
  2. Отримати поля та типи форм
  3. Перевірте, чи містять рядки у визначеному користувачем полі якесь значення

# 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()


Дякуємо за розуміння @MikeT. Документація GDAL / OGR використовує метод "Destroy ()" у всій їх кулінарній книзі. Які проблеми ви бачите з цим методом?
Аарон

1
Бувають ситуації, коли можуть використовуватися segfaults, коли ви використовуєте Destroy (), і це було помилкою дизайну піддавати цей метод у прив'язках. Кращим методом є знешкодження подібних об'єктів GDAL inFeature = None. Кулінарна книга GDAL / OGR не є частиною або написана основним колективом GDAL / OGR.
Майк Т

@MikeT Я відредагував публікацію, щоб включити ваші коментарі - дякую.
Аарон

31

У Python існує багато модулів для читання форм-файлів, старших за ArcPy, дивіться на індекс пакунків Python (PyPi): shapefiles . У GIS SE також є багато прикладів (наприклад, для пошуку [Python] Fiona )

Усі можуть прочитати геометрію, поля та проекції.

  • Старший - osgeo (GDAL / OGR) , подивіться, наприклад, кулінарну книгу Python GDAL / OGR
  • інше рішення - Fiona , також засноване на GDAL / OGR, але простіше у використанні (зі словниками Python: формат GeoJSON).
  • pyshp (shapefile) - чисте рішення Python
  • GeoPandas використовує Fiona для читання / запису форм і Pandas , для інструментів аналізу даних. Потрібно знати Панди, щоб ним користуватися.

Але інші модулі, як PySAL: Бібліотека просторового аналізу Python , Cartopy (які використовують pyshp ) або Matplotlib Basemap, також можуть читати файли форм , серед іншого.

Найпростіший у використанні Fiona , але якщо ви знаєте лише ArcPy, використовуйте pyshp , оскільки osgeo та Fiona вимагають встановити бібліотеку GDAL C / C ++, GeoPandas потребує модуля Pandas, а PySAL - занадто великий (багато, багато інших способів лікування)

Якщо ви хочете , щоб прочитати зміст Шейп, вам не потрібні складні речі, просто використовувати гео інтерфейс протокол (GeoJSON) також реалізований в ArcPy ( ArcPy: AsShape )

З Fiona (як словники Python):

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 (як словники Python)

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 (як словники Python)

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 (як рамки даних Pandas)

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)

* Примітка на геопандах Ви повинні використовувати старіші версії Fiona та GDAL з нею, або вона не встановиться. GDAL: 1.11.2 Fiona: 1.6.0 Geopandas: 0.1.0.dev-

В Інтернеті є багато навчальних посібників і навіть книг ( геопросторовий розвиток Python , вивчення геопросторового аналізу з Python та геопроцедура з Python , в пресі)

Загалом, якщо ви хочете використовувати Python без ArcPy, подивіться на Просте тематичне відображення формфайлу за допомогою Python?


Зауважте, що на головній сторінці Фіони йдетьсяThe 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,

2
Очевидно, питання стосується форм-файлів, а не растр. Вони є іншими модулями для растрових файлів.
ген

Чудова відповідь! Що можна оновити у 2017 році?
Майкл

11

Крім ArcPy є геопросторові бібліотеки Python, які нададуть вам ці можливості. Ось два приклади:

Бібліотека Shapefile Python (pyshp)

GeoPandas

Якщо вас цікавлять інші бібліотеки, ця публікація про важливі геопросторові бібліотеки Python - це гарне місце для пошуку.


1
+1 для pyshp, дуже просто та просто у використанні. Здається, все, що хоче ОП, було б влаштовано.
mr.adam
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.