Crea un livello dinamico per ogni valore univoco

Aug 24 2020

Sono nuovo in ArcPy.

Sto cercando di scrivere uno script che eseguirà un ciclo attraverso i valori univoci in un campo in un FC e creerà livelli dinamici , con query di definizione, per ogni valore univoco.

  • Ciascuno dei layer dinamici punta tutti alla stessa feature class principale.
  • Io non voglio caratteristica classi uscita statica. Ad esempio, non posso utilizzare lo strumento Dividi per attributi per questo.

Ho tentato di adattare uno script ArcPy da una risposta correlata per farlo:

from arcpy import *

mxd = arcpy.mapping.MapDocument("CURRENT")
df = arcpy.mapping.ListDataFrames(mxd, "Layers")[0]
fc = "WO_VW_FGDB"
field = "CLASSIFICATIONID"

env.overwriteOutput = True

#Create cursor to iterate rows
cursor = da.SearchCursor (fc, field)
for row in cursor:
    #sql statement for a single feature
    sql = '"{0}" = \'{1}\''.format (field, row[0])
    #Make layer with sql for one feature only. Use the field value as the layer name.
    MakeFeatureLayer_management (fc, row[0], sql)   
    #Make mapping layer object
    lyr = mapping.Layer(row[0])
    #Add mapping layer object to map
    mapping.AddLayer (df, lyr)
del cursor
mxd.save ()

Quando eseguo lo script in ArcGIS Desktop 10.7.1, viene creato correttamente il primo livello. In effetti, crea effettivamente livelli duplicati.

Ma poi produce un errore:

Runtime error  Traceback (most recent call last):   File "<string>", line 17, in <module>   
File "c:\program files (x86)\arcgis\desktop10.7\arcpy\arcpy\management.py", line 6986, in MakeFeatureLayer     
raise e ExecuteError: ERROR 000622: Failed to execute (Make Feature Layer). Parameters are not valid. 
ERROR 000628: Cannot set input into parameter in_features. 

Che cosa sto facendo di sbagliato?

Risposte

1 AnnaForrest Aug 24 2020 at 11:12

Per prima cosa devi creare un elenco di valori di campo univoci. Usa una funzione come quella di seguito:

def unique_values(table , field, criteria = None):
with arcpy.da.SearchCursor(table, [field], criteria) as cursor:
    
    vals = set({row[0] for row in cursor})
    if (None in vals):
        vals.remove(None)
    if ('' in vals):
        vals.remove('')    
    
    return sorted(vals)

Quindi come un ciclo di passaggio separato attraverso quei valori creando i tuoi livelli. Per esempio

vals = unique_values(fc)
for v in vals :
     
    sql = '"{0}" = \'{1}\''.format (field, v)
    MakeFeatureLayer_management (fc, v, sql)   
    .... 
User1973 Aug 26 2020 at 22:33

Questo script funziona in ArcGIS Pro 2.4 (ma non in ArcGIS Desktop 10.7.1.):

def DuplicateLayer(CopyLayer, field, uniquevalue):
    p = arcpy.mp.ArcGISProject("Current")
    m = p.listMaps("Map")[0]
    LayerToDup = m.listLayers(CopyLayer)[0]
    print(LayerToDup.name)
    m.addLayer(LayerToDup, "AUTO_ARRANGE")
    LayerToDup.name = str(CopyLayer)
    lyr = m.listLayers(CopyLayer)[0]
    lyr.definitionQuery = field + " = '" + uniquevalue + "'"
    lyr.name = uniquevalue
    print (lyr.definitionQuery)
    
def unique_values(layer, field):
    with arcpy.da.SearchCursor(layer, [field]) as cursor:
        return sorted({row[0] for row in cursor})

def ExplodeFC(layername,field):
    fieldvals = unique_values(layername,field)
    for value in fieldvals:
        DuplicateLayer(layername,field,value)
 
ExplodeFC("WO_VW_FGDB","CLASSIFICATIONID")