1 votos

ArcPy falla al calcular el valor de la fuente de los enteros en el campo LONG

Estoy trabajando en un script que itera a través de los registros de "feature class A", realiza una selección espacial (flow tracing) con cada registro individual de "A" en "feature class B" y luego calcula en campo un atributo de "A" en los registros seleccionados resultantes en "B"

Básicamente, para cada nodo situado más abajo en una red de tuberías de alcantarillado, rastrea aguas arriba y asigna el ID de ese nodo aguas abajo a todas las características aguas arriba.

El valor del atributo siempre será un número entero, pero a veces el campo en A se formatea como texto y a veces como número.

Puedo realizar con éxito este cálculo si:

A se formatea como TEXTO

y

B se formatea como LONG

la operación no calcula nada si:

A se formatea como LONG

y

B está formateado como LONG

¿Qué me falta para que esto funcione para ambos casos potenciales de entrada si el ID de A es un número entero de texto o un formato de número entero entero?

...
for row in cursor:
    ID = (str(row.getValue(str(flagname))))
    whereclause = ((str(flagname)) +str(' = ') + "'%s'" %ID)
    fc=str(r"outfalls_lyr")
    arcpy.MakeFeatureLayer_management(traceflag, fc)

    try:
        arcpy.SelectLayerByAttribute_management(fc, "NEW_SELECTION",str(whereclause))
        arcpy.MakeFeatureLayer_management( fc,r"in_memory\temp_of")
        arcpy.TraceGeometricNetwork_management(geomnet, r"in_memory\outNet",r"in_memory\temp_of" , "TRACE_UPSTREAM", "", "", "","", "", "NO_TRACE_ENDS", "NO_TRACE_INDETERMINATE_FLOW", "", "", "AS_IS", "", "", "", "AS_IS")
        for layer in arcpy.mapping.Layer(r"in_memory\outNet"):
            try:
                print arcpy.mapping.ListLayers(layer)
                calc = str('"%s"' %ID)
                arcpy.CalculateField_management (layer, fieldname, calc,"","")
            except:
                print arcpy.GetMessages()

    except:
        print arcpy.GetMessages()

Publicado también en Stack Overflow.

2voto

Son of a Beach Puntos 184

Debe especificar el tipo de expresión (por ejemplo "PYTHON" ), pero esto dependerá de la versión de ArcGIS/arcpy que esté utilizando. "PYTHON" para ArcMap es necesario, si no quiere que por defecto sea "VB" (visual basic!). Usted puede utilizar VB si lo desea, pero sería inusual para incrustar esto en un Python (arcpy) script. (Creo que ArcGIS Pro por defecto a "PYTHON3" ).

Pero creo que el principal problema es que has puesto tu calc para incluir las comillas dobles ( " ) al principio y al final dentro del propio valor de la cadena cuando lo haga: calc = str('"%s"' %ID) . Esto dará como resultado un valor de cadena como "123" INCLUYENDO las comillas dobles que no se pueden convertir en un número.

Intenta esto en su lugar:

arcpy.CalculateField_management(layer, fieldname, ID, "PYTHON", "")

ID ya es una cadena (ya ha sido convertida y convertida en cadena anteriormente en el script), por lo que no es necesario hacerlo de nuevo, y no incluye las problemáticas comillas extra en el valor de la cadena.

Ahora también puedes eliminar la línea: calc = str('"%s"' %ID)

Por otra parte, no utilice str() para convertir cadenas en cadenas. Es redundante y además dificulta la lectura del código. Por ejemplo, str(' = ') no tiene sentido. Sólo usa ' = ' . Utilice únicamente str() si necesitas convertir algo que NO es una cadena en una cadena.

0voto

Rohit Puntos 1279

El problema parece haber estado en cómo se analizó y ejecutó la consulta de selección. Para uno de los tipos de campo, se devolvió una selección vacía, por lo que no se generaron banderas de rastreo a partir de las cuales realizar la selección de rastreo ascendente. esto devolvió un resultado de rastreo vacío, por lo que no había ningún registro en el que calcular el ID.

añadir una prueba para el tipo de campo fuente parece haber resuelto el problema.

Estoy seguro de que hay una forma más eficiente y limpia de escribir esto pero el código actualizado que aparece a continuación SÍ que produce los resultados deseados en ambos casos (el campo fuente es TEXTO o el campo fuente es LARGO), así que es una solución adecuada para mis propósitos.

cursor = arcpy.SearchCursor(traceflag)

fields = arcpy.ListFields(traceflag)
for field in fields:
    if field.name == flagname and field.type == 'String':
        typeIsString = "True"
    elif field.name == flagname and not field.type == 'String':
        typeIsString = "False"

for row in cursor:
    if typeIsString == "True":
        ID = str((row.getValue(str(flagname))))
    elif typeIsString == "False":
        ID = int((row.getValue(str((flagname)))))
whereclause = (flagname + ' = ' + `ID`)
fc=str(r"outfalls_lyr")
arcpy.MakeFeatureLayer_management(traceflag, fc)

try:
    arcpy.SelectLayerByAttribute_management(fc, "NEW_SELECTION",str(whereclause))
    arcpy.MakeFeatureLayer_management( fc,r"in_memory\temp_of")
    arcpy.TraceGeometricNetwork_management(geomnet, r"in_memory\outNet",r"in_memory\temp_of" , "TRACE_UPSTREAM", "", "", "","", "", "NO_TRACE_ENDS", "NO_TRACE_INDETERMINATE_FLOW", "", "", "AS_IS", "", "", "", "AS_IS")
    for layer in arcpy.mapping.Layer(r"in_memory\outNet"):
        try:
            print arcpy.mapping.ListLayers(layer)
            calc = str('"%s"' %ID)
            arcpy.CalculateField_management(layer, fieldname, ID, "PYTHON", "")
        except:
            print arcpy.GetMessages()

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