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?


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

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)

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 .


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"

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.

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.


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
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.