Hi there,
I have a workflow where I publish mobile inspection apps for our inspectors. I am using Pro 3.1.0 and I have automated several steps using Pro Notebooks, but there is one step I am struggling with. After creating a file-based geo-database, I have about 8 or 10 feature classes that need to be symbolized. Some feature classes are rendered all the same, and some are based on unique values. I have a set of LYRX files to utilize, so it's not a huge deal to just import the symbology one layer at a time.
Still, I would like to figure out how to streamline this task. I am still learning Python and I've done lots of research looking for a way to do this. As far as I can tell, there is a GP tool that can take multiple input layers, but only one layer file and all the input layers need to reference that one symbology reference.
I have a Pro Project with about 25 layers, and about 10 of them will be used for publishing the inspection app, the rest are just for reference from out GIS. I want to take my list of 10 layers and 10 layer files and match them up to inherit the symbology.
I have a list of TOC layers and a list of the layer files. I want to create a For loop, go through the layer files, look for an identical layer name in the TOC, and then import the symbology from the layer file to the layer one layer at a time.
I can't figure out how to take a smaller list and compare it to the larger list of TOC layers, then with an If statement (layer names match), process the symbology definition.
I've beginning to understand that layer object pointers in arcpy are different than a list of layer names, which a lot of the GP tools use (string values). I've experimented with Model Builder too, and the Iterators, but it seems that there can only be one source layer definition at a time.
Here is my script so far. I have never used Describe before and I just barely heard of CIM yesterday and wonder if that might be a better approach.
import arcpy
import arcpy.da
import os
aprx = arcpy.mp.ArcGISProject("CURRENT")
# maps = aprx.listMaps("layers")[0]
maps = aprx.listMaps()[0]
map_layer_objs = maps.listLayers()
src_lf_folder = r'G:\Inspection_Work\LayerFiles'
lf_list_str = []
# Get list of Layer files
files = os.listdir(src_lf_folder)
for curFile in files:
print("Layer file found: " + src_lf_folder + curFile)
lf_list.append(curFile)
print(lf_list)
print(aprx)
print(map_layers)
map_layers = [] # list of lists where each sublist contains layer names for each map in project
for m in aprx.listMaps():
lyr_names = [] # initialize an empty list and append layer names to it in every iteration
for lyr in m.listLayers():
lyr_names.append(lyr.name)
map_layers.append(lyr_names)
print(map_layers)
#desc = arcpy.Describe("OH_Poles")
desc = arcpy.da.Describe("OH_Poles")
print("Name String: " + desc.nameString)
print("Where Clause: " + desc.whereClause)
Any help would be much appreciated, thanks,
Bill~
Solved! Go to Solution.
The below will work as long as your layer file folder contains only layer files. If it does not, you may consider using arcpy.da.Walk: Walk—ArcGIS Pro | Documentation which lets you filter by layer file.
This also assumes you are using just one map in the project. If your layers are scattered over more than one map, we'll need to loop through the maps too.
import arcpy
import os
aprx = arcpy.mp.ArcGISProject('CURRENT')
m = aprx.listMaps()[0]
lyrx_folder = r'G:\Inspection_Work\LayerFiles'
lyrx_files = os.listdir(lyrx_folder)
for lyrx in lyrx_files:
lyrx_name = os.path.splitext(lyrx)[0]
lyr = m.listLayers(lyrx_name)
if lyr:
arcpy.management.ApplySymbologyFromLayer(lyr[0],os.path.join(lyrx_folder,lyrx))
Instead of comparing a list of TOC layers to a list of lyrx files, I drop the .lyrx extension and use that name to get the layer from the map. As long as the layer is found, then I have everything I need to apply symbology from the layer file.
The below will work as long as your layer file folder contains only layer files. If it does not, you may consider using arcpy.da.Walk: Walk—ArcGIS Pro | Documentation which lets you filter by layer file.
This also assumes you are using just one map in the project. If your layers are scattered over more than one map, we'll need to loop through the maps too.
import arcpy
import os
aprx = arcpy.mp.ArcGISProject('CURRENT')
m = aprx.listMaps()[0]
lyrx_folder = r'G:\Inspection_Work\LayerFiles'
lyrx_files = os.listdir(lyrx_folder)
for lyrx in lyrx_files:
lyrx_name = os.path.splitext(lyrx)[0]
lyr = m.listLayers(lyrx_name)
if lyr:
arcpy.management.ApplySymbologyFromLayer(lyr[0],os.path.join(lyrx_folder,lyrx))
Instead of comparing a list of TOC layers to a list of lyrx files, I drop the .lyrx extension and use that name to get the layer from the map. As long as the layer is found, then I have everything I need to apply symbology from the layer file.
This works beautifully Daniel!
Thanks so much. I'm not familiar with those os properties and functions but that is slick. For some reason it did not work and kept failing on the last command. But when I checked it again, I missed the last ")" so when I added it back in, it went through the whole map updating the symbology.
I will dress it up with some more IFS and Supports tests. I do have one Annotation layer, but the script didn't stop or bark or anything.
Thanks so much, and have a great rest of your week,
Bill~