10 votos

¿Cómo comprobar mediante programación si el número de formas es igual al número de registros de la tabla?

Tengo un puñado de aproximadamente 1000 shapefiles que están corruptos (ver mensaje de error adjunto). Los archivos shape se generaron con eCognition Developer 8. Hay un herramienta de script que parece reparar el shapefile una vez identificado como corrupto.

enter image description here

Edita:

Quiero crear un script rápido para recorrer todos mis shapefiles y comprobar si el número de shapes coincide con los registros de la tabla. Puedo contar los registros de la tabla utilizando el 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 comprobación lógica como:

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

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

1 votos

Me imagino que el archivo se puede ver, pero ¿son cada uno de los elementos de la tabla de atributos representados por un objeto? de eso se encarga el archivo sbn. independientemente de que muestre el número no coincide. shapefilerepairer es lo que yo uso.

1 votos

Descompilación el script puede ser útil, pero ¡vaya código más antiguo! Sinceramente, me sorprende que todavía funcione con los shapefiles actuales.

1 votos

@Brad He actualizado el post para hacer correcciones. El error .sbn es un problema diferente que he estado teniendo y no está relacionado con este problema.

7voto

Arda Xi Puntos 1099

¿Qué le parece utilizar pyshp ? Lo instalé con pip y lo que he probado a continuación es más o menos directamente de la LÉAME :

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

Por desgracia (¿o por suerte?), no dispongo de ningún archivo shape para comprobar si el número de formas puede ser igual al número de registros.

Espera un momento, ahora sí tengo un shapefile de la hostia gracias a la idea de Kirk en los comentarios de abajo. Hice una copia de seguridad de la dbf, hizo una copia de todo el shapefile, eliminado algunas características, a continuación, cambiar el nombre de la copia de seguridad dbf de nuevo a la 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
>>>

2 votos

Tal vez trate de hacer una copia del archivo de forma (archivos, en realidad). A continuación, en la copia de eliminar algunas características. A continuación, reemplace el dbf original con el dbf copiado (que ha tenido algunas filas eliminadas).

0 votos

@KirkKuykendall - tu idea funcionó, ver ediciones. Gracias.

7 votos

No hay problema. Si alguna vez necesitas que corrompa más datos, dímelo.

5voto

aditya Puntos 111

Por el sonido de su pregunta, parece que todo lo que realmente quiere hacer es determinar si un shapefile tiene o no problemas (en este caso, registros no coincidentes). Si sólo necesita identificar los que tienen problemas, en realidad no es necesario contar los registros en el DBF y Shapefile para determinar si está en error. He aquí por qué:

Si intenta ejecutar la función GetCount en un shapefile 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 quieres hacer es identificar los shapefiles en error, puedes atrapar esto con una cláusula try/except en tu código, en lugar del if/else que estabas intentando usar previamente.

Me he tomado la libertad de añadir el código y el bucle "List FeatureClasses" para que pueda probar todas las FC de su espacio de trabajo sin tener que probar manualmente cada una de ellas.

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

0 votos

Gracias Ryan, esta es una buena alternativa a la solución de Chad y también hace el truco.

2voto

saint_groceon Puntos 2696

El formato shapefile está documentado. Supongo que el número de registros del archivo shp no se corresponde con el número de registros del archivo dbf.

El formato de archivo shp es documentado aquí . Así que usted podría escribir un programa para contar el número de formas. El formato dbf está documentado en muchos sitios y deberías poder encontrar ejemplos para contar filas, por ejemplo aquí .

0 votos

Las filas de un fichero dBase pueden contarse de dos formas: (1) un registro en la cabecera estipula cuántas filas contiene y (2) se resta la longitud de la cabecera de la longitud total del fichero (en bytes) y se divide por la longitud del registro (igual a uno más la suma de longitudes de los campos). Suele ser una buena idea hacer ambas cosas por si el fichero está físicamente truncado. En cualquier caso, aunque los recuentos coincidan, los archivos .shp y .dbf son casi inútiles sin el archivo .shx, que indexa el archivo .shp. Por lo tanto, una comprobación rápida del recuento de registros .shx puede ser mejor que leer todo el archivo .shp.

2voto

Aaron Puntos 25882

El script adjunto recorre un directorio y comprueba si el número de formas coincide con el número de registros de 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"

1voto

SpliFF Puntos 214

Observando el artículo de la wikipedia sobre shapefiles , el archivo .shx debe contener un índice en el archivo .shp, no en el archivo .dbf. Así que puede ser necesario comprobar si .shx y .shp encajan.

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

0 votos

¿A quién "no está permitido"? Es posible recuperar todos la información de las características sólo del archivo .shp.

1 votos

Por el software que espera un índice que funcione bien. No son los términos correctos, he cambiado un poco la respuesta...

i-Ciencias.com

I-Ciencias es una comunidad de estudiantes y amantes de la ciencia en la que puedes resolver tus problemas y dudas.
Puedes consultar las preguntas de otros usuarios, hacer tus propias preguntas o resolver las de los demás.

Powered by:

X