Como verificar programaticamente se o número de formas = número de registros da tabela?

9

Eu tenho um punhado de aproximadamente 1000 shapefiles que estão corrompidos (consulte a mensagem de erro em anexo). Os shapefiles foram gerados a partir do eCognition Developer 8. Existe uma ferramenta de script que parece reparar o shapefile depois que ele é identificado como corrompido.

insira a descrição da imagem aqui

Editar:

Quero criar um script rápido para percorrer todos os meus shapefiles e verificar se o número de formas corresponde aos registros da tabela. Posso contar os registros da tabela usando o seguinte:

# 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

Em última análise, gostaria de criar algum tipo de verificação lógica, como:

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

Como posso contar formas diretamente sem acessar o arquivo .dbf? Ou, em outras palavras, qual é a melhor maneira de verificar programaticamente se o número de formas corresponde ao número de registros da tabela?

Aaron
fonte
11
Eu imagino que o arquivo possa ser visualizado, mas cada um dos itens na tabela de atributos é representado por um objeto? é disso que o arquivo sbn cuida. independentemente de exibir o número não corresponde. shapefilerepairer é o que eu uso.
Brad Brad Nesom
11
Descompilar o script pode ser útil, mas uau, esse é um código antigo! Estou sinceramente surpreso que ainda funcione nos shapefiles de hoje.
Paul
11
@Brad Atualizei a postagem para fazer correções. O erro .sbn é um problema diferente que estou enfrentando e não está relacionado a esse problema.
Aaron
@ Brad Quando executo um arquivo corrompido através do Shape Checker, ele informa: "Não há registros suficientes no arquivo dbf - adicionando espaços em branco".
Aaron

Respostas:

5

Que tal usar o pyshp ? Eu o instalei com o pip e o que tentei abaixo é basicamente direto do README :

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

Infelizmente (ou talvez felizmente?) Não tenho shapefiles levantados para testar, para ver se não. de formas pode! = não. de registros.

Espere um minuto, agora eu tenho um arquivo shapefile levantado, graças à idéia de Kirk nos comentários abaixo. Fiz backup do dbf, fiz uma cópia de todo o shapefile, excluí alguns recursos e renomeei o dbf de backup para o original e eis que o número de formas <número de registros:

>>> sf = shapefile.Reader("/Users/chad/CoalOutcrops.shp")
>>> records = sf.records()
>>> len(records)
33732
>>> shapes = sf.shapes()
>>> len(shapes)
33721
>>>
Chad Cooper
fonte
2
Talvez tente fazer uma cópia do arquivo de forma (arquivos, na verdade). Em seguida, na cópia, exclua alguns recursos. Em seguida, substitua o dbf original pelo dbf copiado (que teve algumas linhas excluídas).
21413 Kirk Kuykendall
@KirkKuykendall - sua ideia deu certo, veja as edições. Obrigado.
Chad Cooper3 /
7
Sem problemas. Se você precisar que eu corrompa mais alguns dados, entre em contato.
21413 Kirk Kuykendall
Obrigado pela ajuda @Chad, o módulo shapefile fez o truque. Postei o script final usado para verificar com êxito meus shapefiles. Havia cerca de 50/1000 arquivos corrompidos.
Aaron
5

Pelo som da sua pergunta, parece que tudo o que você realmente deseja fazer é determinar se um arquivo shapefile tem ou não problemas (nesse caso, registros incompatíveis). Se você apenas precisar identificar aqueles com problemas, não precisará contar os registros no DBF e no Shapefile para determinar se está com erro. Aqui está o porquê:

Se você tentar executar a função GetCount em um shapefile com diferentes contagens de registros, ela falhará com o erro:

ERRO 000229 : Não é possível abrir. Falha na execução (GetCount).

Como a função GetCount falha nesse cenário, e tudo o que você quer fazer é identificar os arquivos shapefiles com erro, você pode capturar isso com uma cláusula try / except no seu código, em vez do if / else que você estava tentando usar anteriormente.

Tomei a liberdade de adicionar o código e o loop "List FeatureClasses" para que você pudesse testar todos os FCs no seu espaço de trabalho sem precisar testar manualmente cada um.

# 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)
RyanKDalton
fonte
Obrigado Ryan, esta é uma boa alternativa à solução de Chad e também faz o truque.
Aaron
2

O formato shapefile está documentado. Eu acho que o número de registros no arquivo shp não corresponde ao número de registros no arquivo dbf.

O formato do arquivo shp está documentado aqui . Então você pode escrever um programa para contar o número de formas. O formato dbf está documentado em muitos lugares e você deve encontrar amostras para contar linhas, por exemplo, aqui .

Kirk Kuykendall
fonte
As linhas em um arquivo do dBase podem ser contadas de duas maneiras: (1) um registro no cabeçalho estipula quantas linhas ele contém e (2) subtrai o comprimento do cabeçalho do comprimento total do arquivo (em bytes) e divide pelo comprimento do registro ( igual a um mais a soma dos comprimentos dos campos). Geralmente, é uma boa ideia fazer as duas coisas, caso o arquivo esteja fisicamente truncado. Independentemente, mesmo quando as contagens coincidem, os arquivos .shp e .dbf são quase inúteis sem o arquivo .shx, que é indexado no arquivo .shp. Portanto, uma verificação rápida da contagem de registros .shx pode ser melhor do que ler o arquivo .shp inteiro.
whuber
2

O script anexado percorre um diretório e verifica se o número de formas corresponde ao número de registros para cada 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"
Aaron
fonte
1

O uso da geometria de verificação deve levar você ao primeiro passo.
A Onus
Repair Geometry permitirá que você selecione a ordem e a prioridade do problema que deseja reparar.
Aqui estão alguns outros links de versões mais antigas . Quando você executa o verificador shapefile, termina com reconstruir o dbf?
Essa é a etapa que cria os registros correspondentes. Ocorreu uma de duas coisas para causar o erro.

  1. O shp possui um objeto (espacial) que foi excluído / descartado por outro software / processo.
  2. O dbf possui um registro que está referenciando geometria nula.
    Várias coisas podem causar isso.
    O shx é na verdade o índice entre os dois.
    Contar formas sem contar registros dbf é apenas metade da solução.
Brad Nesom
fonte
Infelizmente, a geometria do reparo não limpa o erro.
Aaron
1

Analisando o artigo da wikipedia sobre shapefiles , o arquivo .shx deve conter um índice no arquivo .shp, não no arquivo .dbf. Portanto, pode ser necessário verificar se .shx e .shp se encaixam.

É possível abrir um arquivo shapefile sem .dbf (o que significa que você não possui tabela de atributos), mas um índice quebrado gera uma mensagem de erro.

AndreJ
fonte
Por quem "não é permitido"? É possível recuperar todas as informações do recurso apenas do arquivo .shp.
whuber
11
Pelo software que espera um índice que funcione bem. Não os termos corretos, eu mudei a resposta um pouco ...
Andrej