Làm cách nào để thêm trường thuộc tính vào Shapefile hiện tại thông qua Python mà không cần ArcGIS?


24

Tôi có một tập lệnh Python thêm trường thuộc tính vào Shapefile nếu không tồn tại. Điều này rất dễ thực hiện với ArcGIS (đồ họa hoặc thông qua Python), nhưng tôi đang tìm kiếm thứ gì đó không phụ thuộc vào ArcGIS.

Tôi đã thử điều này không thành công với OGR, vì Shapefile của tôi có các tính năng .

Tôi đã xem pyshp , nhưng tương tự không có cách nào để sửa đổi lược đồ sau khi nó được tạo. Tôi chưa thử dùng shapefile (đối với Python) , nhưng tôi không thấy tính năng này được quảng cáo. Tôi cũng không thể thấy làm thế nào điều này có thể được thực hiện bằng cách mày mò với tệp DBF thông qua dbfpy .

Có ai có ý tưởng nào?


Có thể chấp nhận sao chép cấu trúc shapefile hiện có, thêm một cột mới và sau đó điền vào nó dựa trên shapefile ban đầu không?
DavidF


Câu hỏi này phải được đóng lại dưới dạng bản sao của gis.stackexchange.com/q/3623/664 .
whuber

Vâng, về cơ bản là giống nhau. Tôi đã nhìn, nhưng không thấy nó.
Mike T

Câu trả lời:


8

bạn nên xem qua những câu hỏi này vì nó đã được trả lời: Làm thế nào để thêm các thuộc tính Tính năng tùy chỉnh vào Shapefile bằng Python?

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

Nếu bạn muốn có kết quả, chỉ có một shapefile, chỉ cần xóa các tệp đầu vào của bạn ở cuối tập lệnh của bạn.


Điều này cũng tương tự như gis.stackexchange.com/questions/3623/ cảm ơn vì đã đào nó lên
Mike T


4

Nhờ một định dạng khá chết não gọi là DBF, việc thêm các trường vào shapefiles với dữ liệu thuộc tính hiện có là không thể mà không cần viết lại hoặc thêm phần đệm vào DBF. Tôi không biết về một giải pháp đã sẵn sàng, nhưng những gì tôi sẽ làm là viết một kịch bản để tạo một shapefile mới dựa trên một giải pháp hiện có và thêm (các) trường bổ sung vào shapefile mới. Sau đó sao chép dữ liệu hình học / thuộc tính từ shapefile cũ sang mới. Và như là bước cuối cùng, loại bỏ shapefile cũ và đổi tên cái mới. Tất cả điều này khá dễ dàng thực hiện bằng cách sử dụng các ràng buộc python OGR.

Thay phiên, bạn có thể sử dụng dbfpy để thực hiện các thao tác trên chỉ với tệp DBF. Thứ tự các bước vẫn giữ nguyên:

  1. Tạo một DBF mới với cấu trúc giống hệt với bản gốc
  2. Tạo các trường thuộc tính mới trong DBF mới
  3. Sao chép dữ liệu từ DBF gốc sang DBF mới
  4. Xóa DBF cũ, đổi tên DBF mới thành DBF cũ

Bạn không cần thực hiện bất kỳ thay đổi nào đối với chính shapefile (.shp) hoặc bất kỳ tệp nào khác, vì chúng không tham chiếu thông tin thuộc tính có trong DBF. Tuy nhiên, bạn cần phải giữ thứ tự các bản ghi giống hệt nhau trong DBF cũ và mới.


3

DBFpy nên làm việc cho điều này. Bạn đã thấy ví dụ trên trang này:

http://dbfpy.sourceforge.net/

Đảm bảo rằng shapefile không được chỉnh sửa bởi bất kỳ ứng dụng nào khác, kể cả ArcGIS tại thời điểm này vì điều này có thể gây ra sự cố thông qua khóa.


Tôi không nghĩ rằng điều này hoạt động nếu bạn đã có dữ liệu trong tệp DBF. Tôi đã xem xét nó trước đây, nhưng tôi gặp một lỗi: "Ít nhất một bản ghi đã được thêm vào, cấu trúc không thể thay đổi". Bạn có bất kỳ ví dụ cụ thể trong tâm trí?
Mike T

Bây giờ tôi nhớ có, như Sasa nói rằng việc tạo ra một DBF mới sẽ được yêu cầu. Sao chép lược đồ (như trong các trường, v.v.) sau đó thực hiện bổ sung của bạn, sau đó sao chép các bản ghi qua. DBF "vĩ đại" ... :(
Rob Clark

@Mike Làm thế nào một bản ghi được thêm vào khi tất cả những gì bạn muốn làm là thêm một trường ?? Thêm một bản ghi là một lỗi vì nó phá hỏng kết nối giữa các thuộc tính và hình dạng. Thêm một lĩnh vực không có hại gì cả. Bất kỳ thư viện nào có thể chỉnh sửa các tệp dbf sẽ thực hiện công việc đúng cách.
whuber

@whuber: Đó là thông báo lỗi của họ. Mở một dbf hiện có có dữ liệu và xem:from dbfpy import dbf; db = dbf.Dbf('my.dbf'); db.addField(("FOO", "C", 15))
Mike T

@Mike Cảm ơn đã làm rõ tình hình. Nghe có vẻ như là kết quả của một giới hạn không cần thiết trong dbfpy :-(. Tôi có thể đoán tại sao: việc thêm một trường trong cơ sở dữ liệu không trống đòi hỏi tất cả các bản ghi phải được đọc, mở rộng và viết lại một cách vật lý. để tìm thư viện dBase khác hoặc sử dụng phần mềm khác ;-).
whuber

1

Tôi đã tìm thấy một giải pháp bằng OGR và nhờ sự giúp đỡ từ một câu hỏi trước đó . Dưới đây là một ví dụ hoàn chỉnh:

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

Vấn đề của tôi là tôi đã sử dụng layer_defn.AddFieldDefn(new_field)chứ không phải layer.CreateField(new_field). Rất cám ơn sự giúp đỡ, và xin lỗi vì đã không kiểm tra kỹ lưỡng cho câu hỏi tương tự khác.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.