Як додати поле атрибутів до існуючого Shapefile через Python без ArcGIS?


24

У мене є сценарій Python, який додає поле атрибутів до Shapefile, якщо його немає. Це легко зробити з ArcGIS (графічно або через Python), але я шукаю те, що не залежить від ArcGIS.

Я невдало спробував це з OGR, оскільки мій Shapefile містить функції .

Я переглянув pyshp , але аналогічно немає способу змінити схему після її створення. У мене не було спроб з shapefile (для Python) , але я не вважаю, що ця функція рекламується. Я також не бачу, як це можна зробити, поводячись з файлом DBF через dbfpy .

Хтось має ідеї?


Чи було б прийнятним клонувати існуючу структуру формфайлу, додати новий стовпець, а потім заповнити його на основі вихідного файлу форм?
DavidF


Це запитання слід закрити як дублікат gis.stackexchange.com/q/3623/664 .
whuber

Так, по суті те саме. Я дивився, але не бачив.
Майк Т

Відповіді:


8

вам слід ознайомитися з цими питаннями, оскільки на нього вже відповіли: Як додати спеціальні атрибути функції до Shapefile за допомогою Python?

/programming/4215658/adding-custom-feature-attributes-to-esri-shapefile-with-python

Якщо ви хочете, як результат, лише один файл форми, просто видаліть вхідні файли в кінці сценарію.


Що також схоже на gis.stackexchange.com/questions/3623/… Дякуємо, що викопали це
Майк T


4

Завдяки досить мертвому формату, який називається DBF, додавання полів до форм-файлів із наявними даними атрибутів неможливо без перезапису чи додавання прокладки до DBF. Я не знаю готового рішення, але те, що я би зробив, - це написати сценарій, щоб створити новий файл файлів на основі наявного та додати додаткові поля до нового формату. Потім скопіюйте дані геометрії / атрибутів зі старого у новий файл форми. І як завершальний крок, видаліть старий файл форми і перейменуйте новий. Все це досить легко здійснити за допомогою прив'язки пітонів OGR.

Крім того, ви можете використовувати dbfpy, щоб зробити вищезазначене лише за допомогою файлу DBF. Порядок кроків залишається незмінним:

  1. Створіть новий DBF з однаковою структурою для оригіналу
  2. Створіть нові поля атрибутів у новому DBF
  3. Скопіюйте дані з оригінального DBF в новий DBF
  4. Видаліть старий DBF, перейменуйте новий DBF на старий DBF

Вам не потрібно вносити жодних змін у сам файл форми (.shp) або будь-який інший файл, оскільки вони не посилаються на інформацію атрибутів, що міститься у DBF. Однак вам потрібно зберігати порядок записів точно однаковим у старому та новому DBF.


3

DBFpy повинен працювати для цього. Ви бачили приклад на цій сторінці:

http://dbfpy.sourceforge.net/

Переконайтеся, що файл форми не редагується жодною іншою програмою, включаючи ArcGIS, оскільки це може спричинити проблеми через блокування.


Я не думаю, що це працює, якщо у вас вже є дані у файлі DBF. Я раніше це переглядав, але отримую помилку: "Принаймні один запис було додано, структуру неможливо змінити". Чи маєте ви на увазі якийсь конкретний приклад?
Майк Т

Ага, я пам'ятаю, так, як Саса сказав, що потрібно створити новий DBF. Скопіюйте схему (як у поля тощо), а потім зробіть свої доповнення, а потім скопіюйте записи впоперек. "Великий" DBF ... :(
Роб Кларк

@Mike Як було додано запис, коли все, що ви хочете зробити, це додати поле ?? Додавання запису - помилка, оскільки це руйнує зв'язок між атрибутами та формами. Додавання поля зовсім не шкодить. Будь-яка бібліотека, яка може редагувати файли dbf, виконає цю роботу належним чином.
whuber

@whuber: Це їх повідомлення про помилку. Відкрийте існуючий dbf, у якому є дані, і подивіться:from dbfpy import dbf; db = dbf.Dbf('my.dbf'); db.addField(("FOO", "C", 15))
Майк T

@Mike Дякую за роз’яснення ситуації. Це звучить як результат зайвого обмеження в dbfpy :-(. Я можу здогадатися, чому: додавання поля в не порожню базу даних вимагає фізичного зчитування, розширення та повторного запису всіх записів. Хорошим рішенням є знайти іншу бібліотеку dBase або використовувати інше програмне забезпечення ;-).
whuber

1

Я знайшов рішення за допомогою OGR і завдяки допомозі в попередньому питанні . Ось повний приклад:

from osgeo import ogr

# Open a Shapefile, and get field names
source = ogr.Open('my.shp', update=True)
layer = source.GetLayer()
layer_defn = layer.GetLayerDefn()
field_names = [layer_defn.GetFieldDefn(i).GetName() for i in range(layer_defn.GetFieldCount())]
print len(field_names), 'MYFLD' in field_names

# Add a new field
new_field = ogr.FieldDefn('MYFLD', ogr.OFTInteger)
layer.CreateField(new_field)

# Close the Shapefile
source = None

Моя проблема полягала в тому, що я layer_defn.AddFieldDefn(new_field)скоріше використовував layer.CreateField(new_field). Велике спасибі за допомогу, і вибачте, що не ретельно перевіряєте подібне інше питання.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.