Làm thế nào để kiểm tra theo chương trình nếu số lượng hình = số bản ghi bảng?


9

Tôi có một số khoảng 1000 shapefile bị hỏng (xem thông báo lỗi đính kèm). Các shapefile được tạo từ eCognition Developer 8. Có một công cụ tập lệnh dường như sửa chữa shapefile một khi nó được xác định là bị hỏng.

nhập mô tả hình ảnh ở đây

Biên tập:

Tôi muốn tạo một tập lệnh nhanh để lặp qua tất cả các shapefile của mình và kiểm tra xem số lượng hình có khớp với các bản ghi bảng không. Tôi có thể đếm các bản ghi bảng bằng cách sử dụng như sau:

# Name: fcCount.py
# Purpose: calculate the number of features in a featureclass

# Import system modules
import arcpy
from arcpy import env

env.workspace = "C:/data"
Sample = "MyShp.shp"
result_dbf = int(arcpy.GetCount_management(Sample).getOutput(0)) 
print result_dbf

Cuối cùng tôi muốn tạo ra một số loại kiểm tra logic như:

if result_dbf = result_shp:
    pass
else:
    print "There is a problem with" + str(Sample)

Làm cách nào để đếm hình trực tiếp mà không cần truy cập tệp .dbf? Hay nói cách khác, cách tốt nhất để kiểm tra theo chương trình nếu số lượng hình phù hợp với số lượng bản ghi bảng là gì?


1
Tôi tưởng tượng tập tin có thể được xem, nhưng mỗi mục trong bảng thuộc tính được đại diện bởi một đối tượng? đó là những gì tập tin sbn quan tâm. bất kể nó hiển thị số không khớp. shapefilerepairer là những gì tôi sử dụng.
Brad Nesom

1
Dịch ngược kịch bản có thể hữu ích, nhưng wow đó là một số mã cũ! Tôi thực sự ngạc nhiên khi nó vẫn hoạt động trên các shapefiles ngày nay.
Paul

1
@Brad Tôi đã cập nhật bài viết để chỉnh sửa. Lỗi .sbn là một vấn đề khác tôi đã gặp phải và không liên quan đến vấn đề này.
Aaron

@Brad Khi tôi chạy một tệp bị hỏng thông qua Trình kiểm tra hình dạng, nó báo cáo: "Không đủ bản ghi trong tệp dbf - thêm khoảng trống".
Aaron

Câu trả lời:


5

Còn việc sử dụng pyshp thì sao? Tôi đã cài đặt nó với pip và những gì tôi đã thử bên dưới khá nhiều so với README :

>>> import shapefile
>>> sf = shapefile.Reader("/Users/chad/CoalOutcrops.shp")
>>> shapes = sf.shapes()
>>> len(shapes)
33732
>>> records = sf.records()
>>> len(records)
33732
>>>

Thật không may (hoặc có thể may mắn thay?) Tôi không có bất kỳ shapefile jack-up nào để kiểm tra xem có không. của hình dạng có thể! = không. của hồ sơ.

Đợi một chút, bây giờ tôi đã có một shapefile jacked nhờ ý tưởng của Kirk trong các ý kiến ​​dưới đây. Tôi đã sao lưu dbf, tạo một bản sao của toàn bộ shapefile, xóa một số tính năng, sau đó đổi tên dbf sao lưu trở lại ban đầu, và lo và kìa, số lượng hình dạng <số lượng bản ghi:

>>> sf = shapefile.Reader("/Users/chad/CoalOutcrops.shp")
>>> records = sf.records()
>>> len(records)
33732
>>> shapes = sf.shapes()
>>> len(shapes)
33721
>>>

2
Có thể thử tạo một bản sao của tệp hình dạng (tệp, thực sự). Sau đó trong bản sao xóa một số tính năng. Sau đó thay thế dbf gốc bằng dbf đã sao chép (đã bị xóa một số hàng).
Kirk Kuykendall

@KirkKuykendall - ý tưởng của bạn đã hoạt động, xem các chỉnh sửa. Cảm ơn.
Chad Cooper

7
Không vấn đề gì. Nếu bạn cần tôi làm hỏng thêm một số dữ liệu, hãy cho tôi biết.
Kirk Kuykendall

Cảm ơn sự giúp đỡ @Chad, mô-đun shapefile đã thực hiện thủ thuật này. Tôi đã đăng kịch bản cuối cùng được sử dụng để kiểm tra thành công shapefiles của tôi. Có khoảng 50/1000 tệp bị hỏng.
Aaron

5

Từ âm thanh của câu hỏi của bạn, có vẻ như tất cả những gì bạn thực sự muốn làm là xác định xem một shapefile có vấn đề với nó hay không (trong trường hợp này là các bản ghi không khớp). Nếu bạn chỉ cần xác định những người có vấn đề, bạn thực sự không cần phải đếm các bản ghi trong DBF và Shapefile để xác định xem nó có bị lỗi hay không. Đây là lý do tại sao:

Nếu bạn cố chạy chức năng GetCount trên một shapefile có số lượng bản ghi khác nhau, nó sẽ thất bại với lỗi:

ERROR 000.229 : Không thể mở. Không thể thực thi (GetCount).

Vì hàm GetCount không thành công trong kịch bản này và tất cả những gì bạn muốn làm là xác định các shapefile bị lỗi, bạn có thể bắt gặp điều này với mệnh đề try / trừ trong mã của bạn, thay vì if / other trước đây bạn đang cố sử dụng.

Tôi đã tự do thêm mã và vòng lặp "Danh sách tính năng" để bạn có thể kiểm tra tất cả các FC trong không gian làm việc của mình mà không phải kiểm tra thủ công từng cái.

# Import system modules
import arcpy
from arcpy import env

env.workspace = "C:/data"

fcList = arcpy.ListFeatureClasses()

for fc in fcList:
    try:
        result_dbf = int(arcpy.GetCount_management(fc).getOutput(0))
        print fc + ": " + str(result_dbf) + " records"
    except:
        print "There is a problem with: " + str(fc)

Cảm ơn Ryan, đây là một giải pháp thay thế tốt cho giải pháp của Chad và cũng thực hiện thủ thuật này.
Aaron

2

Các định dạng shapefile được ghi lại. Tôi đoán số lượng bản ghi trong tệp shp không tương ứng với số lượng bản ghi trong tệp dbf.

Định dạng tệp shp được ghi lại ở đây . Vì vậy, bạn có thể viết một chương trình để đếm số lượng hình dạng. Định dạng dbf được ghi lại ở nhiều nơi và bạn sẽ có thể tìm thấy các mẫu để đếm hàng, ví dụ ở đây .


Hàng trong tệp dBase có thể được tính theo hai cách: (1) bản ghi trong tiêu đề quy định số lượng hàng chứa và (2) trừ chiều dài tiêu đề khỏi tổng chiều dài tệp (tính bằng byte) và chia cho chiều dài bản ghi ( bằng một cộng với tổng độ dài của các trường). Đó thường là một ý tưởng tốt để làm cả hai trong trường hợp tập tin bị cắt ngắn. Bất kể, ngay cả khi số đếm khớp nhau, các tệp .shp và .dbf gần như vô dụng nếu không có tệp .shx, chỉ mục vào tệp .shp. Vì vậy, kiểm tra nhanh số lượng bản ghi .shx có thể tốt hơn đọc toàn bộ tệp .shp.
whuber

2

Tập lệnh đính kèm lặp qua một thư mục và kiểm tra xem số lượng hình có khớp với số lượng bản ghi cho mỗi shapefile không.

import arcpy, os, shapefile
from arcpy import env

env.workspace = r"C:\path\to\shapefiles"
Dir = env.workspace

fclist = arcpy.ListFeatureClasses()

for fc in fclist:

    myfc = os.path.join(Dir, fc)
    sf = shapefile.Reader(str(myfc))
    shapes = sf.shapes()
    shape_total = len(shapes)
    records = sf.records()
    record_total = len(records)

    if shape_total != record_total:
        print "There is a problem with " + str(fc)
    else:
        print str(fc) + " passed"

1

Sử dụng hình học kiểm tra sẽ giúp bạn vượt qua bước đầu tiên.
Onus
Repair Geometry sẽ cho phép bạn chọn thứ tự và mức độ ưu tiên của vấn đề bạn muốn sửa chữa.
đây là một số liên kết phiên bản cũ hơn . Khi bạn chạy trình kiểm tra shapefile, sau đó bạn kết thúc với việc xây dựng lại dbf?
Đó là bước tạo ra các hồ sơ để phù hợp. Một trong hai điều đã xảy ra để gây ra lỗi.

  1. Shp có một đối tượng (không gian) đã bị xóa / bỏ bởi một phần mềm / quy trình khác.
  2. Dff có một bản ghi tham chiếu hình học null.
    Một số điều có thể gây ra điều này.
    Các shx thực sự là chỉ số giữa hai.
    Đếm các hình dạng mà không đếm các bản ghi dbf chỉ là một nửa của giải pháp.

Thật không may, hình học sửa chữa không xóa lỗi.
Aaron

1

Nhìn vào bài viết wikipedia về shapefiles , tệp .shx nên chứa một chỉ mục trên tệp .shp, không phải trên tệp .dbf. Vì vậy, có thể cần phải kiểm tra xem .shx và .shp có khớp với nhau không.

Có thể mở một shapefile mà không cần .dbf (có nghĩa là bạn không có bảng thuộc tính), nhưng một chỉ mục bị hỏng sẽ tạo ra một thông báo lỗi.


Nó "không được phép" của ai? Có thể khôi phục tất cả các thông tin tính năng chỉ từ tệp .shp.
whuber

1
Bởi phần mềm mong đợi một chỉ số hoạt động tốt. Không đúng điều khoản, tôi đã thay đổi câu trả lời một chút ...
AndreJ
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.