I have 40 layers with the same table schema and I need to apply symbology and table settings from another layer. I have a template layer and applying symbology works as expected.
Is it possible to apply fields visibility and formats as well?
I can see pasteProperties (source_layer, {layer_paste_properties}) method but when applying in on a layer object I get the following error: AttributeError: 'Layer' object has no attribute 'pasteProperties'
L = map.addDataFromPath(r"..\Address.lyrx")
for lyr in map.listLayers():
print(lyr.name)
lyr.pasteProperties(L, layer_paste_properties="FIELD_PROPERTIES")
Thanks,
Layer—ArcGIS Pro | Documentation
you should check if it is a featurelayer before trying to try to pastProperties
isFeatureLayer
(Read Only)
Returns True if a layer is a feature layer.
Try this,
import arcpy
# Load the template layer
template_layer_path = r"..\Address.lyrx"
template_layer = arcpy.mp.LayerFile(template_layer_path).listLayers()[0]
# Get your map
aprx = arcpy.mp.ArcGISProject("CURRENT")
map = aprx.listMaps("Your Map Name")[0]
# Apply symbology + field properties
for lyr in map.listLayers():
if lyr.isFeatureLayer:
print(f"Updating {lyr.name}...")
arcpy.management.UpdateLayer(lyr, template_layer, True) # True = keep data source
print(f"Completed: {lyr.name}")
print("All layers updated successfully!")
Didn't work..
AttributeError: module 'arcpy.management' has no attribute 'UpdateLayer'
try
# Use ApplySymbologyFromLayer arcpy.ApplySymbologyFromLayer_management(lyr, template_layer)
I'd just use the CIM definition object, since all these properties can be set directly using dictionaries/CIM objects:
from typing import Any
from arcpy.management import MakeFeatureLayer
from arcpy.cim.CIMVectorLayers import CIMFeatureLayer
from arcpy.mp import ArcGISProject
from arcpy._mp import Layer, Map
def get_state(lyr: Layer) -> dict[str, Any]:
layer_cim: CIMFeatureLayer = lyr.getDefinition('V3')
states_to_save = [
'snappable',
'selectable',
'visibility',
'expanded',
'labelVisibility',
]
return {k:v for k, v in layer_cim.__dict__ if k in states_to_save}
def apply_state(lyr: Layer, state: dict[str, Any]) -> None:
if not lyr.isFeatureLayer:
return
layer_cim: CIMFeatureLayer = lyr.getDefinition('V3')
layer_cim.__dict__.update(state)
lyr.setDefinition(layer_cim)
The first function will pull states from a layer and the second will apply those states to a layer. In your case, you can put these in a loop for the map:
...
def update_map_layers(mp: Map, state: dict[str, Any]) -> None:
for layer in filter(lambda m: m.isFeatureLayer, mp.listLayers()):
apply_state(layer, state)
def main():
template_layer = MakeFeatureLayer(r'<path/to/template>.lyrx')[0]
state = get_state(template_layer)
project = ArcGISProject('<path/to/project>.aprx || CURRENT')
mp = project.listMaps('<map_name>')[0]
update_map_layers(mp, state)
if __name__ == '__main__':
main()