¿Cómo verificar mediante programación si el número de formas = número de registros de la tabla?

9

Tengo un puñado de aproximadamente 1000 shapefiles que están dañados (vea el mensaje de error adjunto). Los archivos de forma se generaron a partir de eCognition Developer 8. Existe una herramienta de script que parece reparar el archivo de forma una vez que se identifica como dañado.

ingrese la descripción de la imagen aquí

Editar:

Quiero crear una secuencia de comandos rápida para recorrer todos mis archivos de formas y verificar si el número de formas coincide con los registros de la tabla. Puedo contar registros de tabla usando lo siguiente:

# 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

En última instancia, me gustaría crear algún tipo de verificación lógica como:

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

¿Cómo puedo contar formas directamente sin acceder al archivo .dbf? O, en otras palabras, ¿cuál es la mejor manera de verificar mediante programación si el número de formas coincide con el número de registros de la tabla?

Aaron
fuente
1
Me imagino que el archivo se puede ver, pero ¿cada elemento de la tabla de atributos está representado por un objeto? de eso se ocupa el archivo sbn. independientemente de si muestra el número no coincide. shapefilerepairer es lo que uso.
Brad Nesom
1
Descompilar el script puede ser útil, pero ¡vaya, es un código antiguo! Sinceramente, me sorprende que todavía funcione en los archivos de forma actuales.
Paul
1
@Brad Actualicé la publicación para hacer correcciones. El error .sbn es un problema diferente que he tenido y no está relacionado con este problema.
Aaron
@Brad Cuando ejecuto un archivo dañado a través del Comprobador de forma, informa: "No hay suficientes registros en el archivo dbf, agregando espacios en blanco".
Aaron

Respuestas:

5

¿Qué pasa con el uso de pyshp ? Lo instalé con pip y lo que probé a continuación es casi directo de README :

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

Desafortunadamente (¿o quizás afortunadamente?) No tengo ningún archivo de forma para probar para ver si no. de formas puede! = no. de registros.

Espere un minuto, ahora tengo un archivo de forma levantado gracias a la idea de Kirk en los comentarios a continuación. Realicé una copia de seguridad del dbf, hice una copia de todo el archivo de forma, eliminé algunas características, luego cambié el nombre del dbf respaldado por el original, y he aquí, el 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
fuente
2
Tal vez intente hacer una copia del archivo de forma (archivos, en realidad). Luego, en la copia, elimine algunas funciones. Luego reemplace el dbf original con el dbf copiado (que ha eliminado algunas filas).
Kirk Kuykendall
@KirkKuykendall: su idea funcionó, vea las ediciones. Gracias.
Chad Cooper
77
No hay problema. Si alguna vez necesita que corrompa algunos datos más, solo avíseme.
Kirk Kuykendall
Gracias por la ayuda @Chad, el módulo shapefile hizo el truco. Publiqué el guión final utilizado para verificar con éxito mis archivos de forma. Había alrededor de 50/1000 archivos corruptos.
Aaron
5

Por el sonido de su pregunta, parece que todo lo que realmente quiere hacer es determinar si un archivo shape tiene o no problemas (en este caso, registros no coincidentes). Si solo necesita identificar a aquellos con problemas, en realidad no necesita contar los registros en el DBF y Shapefile para determinar si se trata de un error. Este es el por qué:

Si intenta ejecutar la función GetCount en un archivo de forma que tiene diferentes recuentos de registros, fallará con el error:

ERROR 000229 : no se puede abrir. Error al ejecutar (GetCount).

Dado que la función GetCount falla en este escenario, y todo lo que desea hacer es identificar los archivos de forma por error, puede detectar esto con una cláusula try / except en su código, en lugar del if / else que intentaba usar anteriormente.

Me tomé la libertad de agregar el código y el bucle "List FeatureClasses" para que pueda probar todos los FC en su espacio de trabajo sin tener que probarlos manualmente.

# 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
fuente
Gracias Ryan, esta es una buena alternativa a la solución de Chad y también funciona.
Aaron
2

El formato del archivo de forma está documentado. Supongo que el número de registros en el archivo shp no corresponde al número de registros en el archivo dbf.

El formato de archivo shp se documenta aquí . Entonces podrías escribir un programa para contar el número de formas. El formato dbf está documentado en muchos lugares y debería poder encontrar muestras para contar filas, por ejemplo, aquí .

Kirk Kuykendall
fuente
Las filas en un archivo dBase se pueden contar de dos maneras: (1) un registro en el encabezado estipula cuántas filas contiene y (2) resta la longitud del encabezado de la longitud total del archivo (en bytes) y se divide por la longitud del registro ( igual a uno más la suma de las longitudes de los campos). Por lo general, es una buena idea hacer ambas cosas en caso de que el archivo esté truncado físicamente. De todos modos, incluso cuando los recuentos coinciden, los archivos .shp y .dbf son casi inútiles sin el archivo .shx, que se indexa en el archivo .shp. Por lo tanto, una comprobación rápida del recuento de registros .shx podría ser mejor que leer todo el archivo .shp.
whuber
2

El script adjunto recorre un directorio y comprueba si el número de formas coincide con el número de registros para cada archivo de formas.

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

El uso de la geometría de verificación debería ayudarlo a pasar el primer paso.
Onus
Repair Geometry le permitirá seleccionar el orden y la prioridad del problema para el que desea reparar.
Aquí hay otros enlaces de versiones anteriores . Cuando ejecutas el verificador de shapefile, ¿terminas con reconstruir dbf?
Ese es el paso que crea los registros para que coincidan. Se ha producido una de dos cosas para causar el error.

  1. El shp tiene un objeto (espacial) que ha sido eliminado / eliminado por otro software / proceso.
  2. El dbf tiene un registro que hace referencia a la geometría nula.
    Varias cosas pueden causar esto.
    El shx es en realidad el índice entre los dos.
    Contar formas sin contar registros dbf es solo la mitad de la solución.
Brad Nesom
fuente
Desafortunadamente, la reparación de la geometría no borra el error.
Aaron
1

Mirando el artículo de wikipedia sobre archivos de forma , el archivo .shx debe contener un índice en el archivo .shp, no en el archivo .dbf. Por lo tanto, podría ser necesario verificar si .shx y .shp encajan entre sí.

Es posible abrir un archivo de forma sin .dbf (lo que significa que no tiene una tabla de atributos), pero un índice roto generará un mensaje de error.

AndreJ
fuente
¿Por quién está "no permitido"? Es posible recuperar toda la información de la función solo desde el archivo .shp.
whuber
1
Por el software que espera un índice que funcione bien. No son los términos correctos, cambié un poco la respuesta ...
AndreJ