如何以编程方式检查形状的数量=表记录的数量?


9

我有大约1000个shapefile已损坏(请参阅附件的错误消息)。shapefile是从eCognition Developer 8生成的。有一个脚本工具似乎可以在将shapefile识别为损坏后对其进行修复。

在此处输入图片说明

编辑:

我想创建一个快速脚本来遍历我所有的shapefile,并检查形状的数量是否与表记录匹配。我可以使用以下方法对表记录进行计数:

# 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

我最终想创建某种逻辑检查,例如:

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

如何在不访问.dbf文件的情况下直接计算形状?或者换句话说,以编程方式检查形状的数量是否与表记录的数量匹配的最佳方法是什么?


1
我想可以查看该文件,但是属性表中的每个项目都由一个对象表示吗?这就是sbn文件要处理的内容。无论显示的数字是否不匹配。shapefilerepairer是我使用的。
Brad Nesom

1
反编译脚本可能有用,但是哇,那是一些旧代码!老实说,我很惊讶它仍然适用于当今的shapefile。
保罗

1
@Brad我更新了帖子以进行更正。.sbn错误是我遇到的另一个问题,并且与该问题无关。
亚伦

@Brad当我通过Shape Checker运行损坏的文件时,它报告:“ dbf文件中没有足够的记录-添加空白”。
亚伦

Answers:


5

那使用pyshp呢?我用pip安装了它,下面尝试的几乎是自述文件

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

不幸的是(或者幸运的是?)我没有任何可测试的shapefile来测试是否为否。形状可以!=否。记录。

请稍等,由于Kirk在下面的评论中的想法,我现在有了一个shapefile。我备份了dbf,制作了整个shapefile的副本,删除了一些功能,然后将备份的dbf重命名回原始文件,瞧瞧,形状的数量<记录的数量:

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

2
也许尝试复制形状文件(实际上是文件)。然后在副本中删除一些功能。然后,用复制的dbf(已删除一些行)替换原始dbf。
Kirk Kuykendall

@KirkKuykendall-您的想法成功了,请参阅编辑。谢谢。
乍得·库珀

7
没问题。如果您需要我破坏更多数据,请告诉我。
Kirk Kuykendall

感谢@Chad的帮助,shapefile模块可以解决问题。我发布了用于成功检查我的shapefile的最终脚本。大约有50/1000个损坏的文件。
亚伦

5

从您的疑问中看来,您似乎真正想要做的只是确定shapefile是否存在问题(在这种情况下,记录不匹配)。如果您只需要确定有问题的对象,则实际上不需要统计DBF和Shapefile中的记录来确定是否有错误。原因如下:

如果您尝试在具有不同记录计数的shapefile上运行GetCount函数,它将失败并显示以下错误:

错误000229:无法打开。执行失败(GetCount)。

由于GetCount函数在这种情况下会失败,并且您要做的就是识别错误的shapefile,因此可以在代码中使用try / except子句来捕获此文件,而不是之前尝试使用的if / else。

我随意添加“列出FeatureClasses”代码并进行循环,以便您可以测试工作区中的所有FC,而无需手动测试每个FC。

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

感谢Ryan,这是Chad解决方案的一个不错的选择,并且也可以解决问题。
亚伦

2

shapefile格式已记录。我猜想shp文件中的记录数与dbf文件中的记录数不对应。

shp文件格式在此处记录。因此,您可以编写一个程序来计算形状的数量。dbf格式在许多地方都有记录,您应该能够找到用于计数行的样本,例如here


可以通过两种方式对dBase文件中的行进行计数:(1)标头中的记录规定了它包含的行数;(2)从文件总长度(以字节为单位)中减去标头长度,然后除以记录长度(等于一加上字段长度的总和)。通常,在文件被物理截断的情况下,最好同时执行这两个操作。无论如何,即使计数匹配,没有.shx文件(索引到.shp文件),. shp和.dbf文件也几乎是无用的。因此,快速检查.shx记录的数量可能比读取整个.shp文件更好。
ub

2

附加的脚本循环遍历目录,并检查形状的数量是否与每个shapefile的记录数量相匹配。

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

使用检查几何图形应该可以帮助您完成第一步。
Onus
Repair Geometry将允许您选择要修复的问题的顺序和优先级。
这是其他一些旧版本的链接。当您运行shapefile checker时,您是否需要重新构建dbf?
这是创建要匹配的记录的步骤。发生了两件事之一导致该错误。

  1. shp具有一个已被另一个软件/进程删除/删除的对象(空间)。
  2. dbf包含引用空几何的记录。
    有几件事会导致此。
    shx实际上是两者之间的索引。
    不计算dbf记录而计算形状只是解决方案的一半。

不幸的是,修复几何无法清除错误。
亚伦

1

查看关于shapefile维基百科文章,.shx文件应在.shp文件上包含索引,而不是.dbf文件上的索引。因此,可能有必要检查.shx和.shp是否合适。

可以打开不带.dbf的shapefile(这意味着您没有属性表),但是索引损坏将生成错误消息。


由谁“不允许”?可以仅从.shp文件恢复所有功能信息。
Whuber

1
通过期望功能良好的索引的软件。用词不正确,我改变了答案……
AndreJ
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.