Estoy escribiendo un script automatizado para hacer algo de procesamiento de datos de puntos de dirección. Una etapa del proceso es recuperar 19 campos de información de diversas polígono capas que los Puntos de Dirección, y rellenar pre-creados los campos en la Dirección de la clase de entidad. De los 19 campos, la mayoría son de Texto, pero un par de Dobles.
En lugar de codificar todos los 19, estoy usando un SearchCursor para hacer un ciclo a través de una tabla de todos los 19 campos, cada uno con su tipo, la longitud, la característica de origen de clase, y el nombre de campo de origen. El SearchCursor primero se crea el campo a las especificaciones y, a continuación, ejecuta el código (abajo) para recuperar el campo de la fuente de datos. La característica de origen de las clases se propagan a través de un SDE y una geodatabase construidos a propósito para este proceso.
De estos 19 campos me estoy uniendo, 9 campos están fallando, y todos están fallando en la misma manera - la inicial de unión Espacial es devolver un valor Null. Esto debería devolver una clase de entidad de punto con la dirección del punto de FID y el campo de destino valor en un campo llamado "Scratch_Da". Sobre el problema de los campos de la unión Espacial de las salidas, "Scratch_Da" es NULO todo el camino hacia abajo. La mayoría de los datos del problema de las fuentes están en el origen de la SDE, pero que se muevan a la geodatabase no resolver los problemas, y dos problema son los campos que vienen de la misma fuente de datos como un campo que funciona bien. He comprobado que la mayoría de la dirección de los puntos están dentro de la asignatura de polígonos y todos los nombres de campo y tipos son correctos.
Alguien ha visto a un ArcPy Espacial Unirse a actuar de esta manera antes?
Aquí está el Campo Espacial bucle de Recuperación:
with arcpy.da.SearchCursor("X:\AddressStage.gdb\SFRFields", SFRList) as cursor:
for row in cursor:
fname = row[0]
ftype = row[1]
fleng = row[2]
fscal = row[3]
fsrc = row[4]
lyr = row[5]
fsfld = row[6]
#create fields with parameters given
arcpy.AddField_management("CPLayer", fname, ftype, fleng, fscal, fleng)
#if field source value is PARSE:
if fsrc == "PARSE":
#use continue to start next iteration
continue
elif fsrc!= "BLANK":
#Begin spatial field retrieval code
#Start by selecting CPLayer features with proper spatial relationship
arcpy.SelectLayerByLocation_management("CPLayer", "WITHIN", fsrc)
loopStart = time.time()
runTime = loopStart - startTime
log.write("{0}:\n".format(fname))
log.write("{0} seconds elapsed in script.\n".format(runTime))
print("Beginning retrieval of field {0}. {1} seconds elapsed in script.".format(fname, runTime))
#perform SFR on nested field, using parameters in SFRFields
#Layer to be calculated
InLayer = "CPLayer"
#InField: Layer which will receive final data
InField = fname
#SourceLayer: Layer which contributes data.
SourceLayer = fsrc
#SourceField: source field
SourceField = fsfld
#SpatShip = spatial relationship - same as Spatial Join tool
SpatShip = "WITHIN"
#MergeRule: How to handle one-to-many relationships
if ftype == "TEXT":
MergeRule = "FIRST"
elif ftype == "DOUBLE":
MergeRule = "SUM"
#SearchDist: search distance
SearchDist = 0
#parse name of SJ features
SJFeat = str("SJ_" + lyr + "_" + fname)
log.write("Output feature class: {0}\n".format(SJFeat))
#Create a field map that changes the InField name to Scratch_Da, and
#uses Sourcefield as input.
#This is so the eventual spatial join features have only the TARGET_FID
#and the target data.
InpFM = arcpy.FieldMap()
ScratchFMS = arcpy.FieldMappings()
InFieldList = arcpy.ListFields(InLayer)
for field in InFieldList:
if field.name == InField:
InpFM.addInputField(SourceLayer, SourceField)
InpFM.mergeRule = MergeRule
#set output field name to Scratch_Data
scratch_name = InpFM.outputField
scratch_name.name = "Scratch_Da"
InpFM.outputField = scratch_name
ScratchFMS.addFieldMap(InpFM)
#spatial join to scratch features
sjTime = time.time()
arcpy.SpatialJoin_analysis(InLayer, SourceLayer, SJFeat, "JOIN_ONE_TO_ONE",
"KEEP_ALL", ScratchFMS, SpatShip, SearchDist)
runTime = time.time() - sjTime
log.write("Spatial join completed. {0} seconds elapsed in spatial join.\n".format(runTime))
#create dictionary object for join purposes.
#the key will be the Target FID, and the value is the target field value.
JoinDict = {}
noneCount = 0
with arcpy.da.SearchCursor(SJFeat, ("TARGET_FID","Scratch_Da")) as cursor:
for row in cursor:
fid = row[0]
val = row[1]
if val == None and ftype == "DOUBLE":
val = 0
noneCount += 1
elif ftype == "DOUBLE" and val <> None:
val = float(row[1])
elif ftype == "TEXT" and val <> None:
val = str(row[1])[:fleng]
elif ftype == "TEXT" and val == None:
val = "FAIL"
noneCount += 1
JoinDict[fid] = val
#Update cursor, hinges on dictionary
with arcpy.da.UpdateCursor(InLayer, ("OID@", InField)) as cursor:
#reach into dictionary using FID values
for row in cursor:
#Search for dictionary item with feature's FID as key
val = JoinDict[row[0]]
row[1] = str(val)
cursor.updateRow(row)
#delete ScratchSJ file.
#arcpy.Delete_management("ScratchSJ")
loopTime = time.time() - loopStart
log.write("Field retrieval completed. {0} seconds elapsed in loop.\n".format(loopTime))
log.write("{0} None values retrieved.\n\n".format(noneCount))
#end of SFR loop
Actualización 03/21/2016: El script se sigue produciendo la NULA comportamiento. El problema de los campos:
- 4 son de texto, de longitudes de 4 a 20 caracteres. La entrada y salida de las longitudes de partido.
- 4 son dobles. Longitud y precisión partido especificaciones de salida, pero las entradas son enteros cortos y no puedo cambiar eso. Sin embargo, la inclusión de los campos de texto entre el campo de problema me llevan a creer que el tipo de campo o la longitud no es un problema.
- 2 campos de texto, vienen de la misma fuente de datos como otro campo de texto que funciona a la perfección.
- He exportado un solo problema de los campos de fila de la tabla que controla el Campo Espacial bucle de Recuperación, y corrió a través del mismo código. El NULO comportamiento persistió cuando hice esto con tanto Texto y haga Doble campos.