Adding feature class and applying symbology in ArcGIS Pro using arcpy

9506
27
06-13-2018 09:40 PM
SeanHough
New Contributor II

Using an arcpy script run from a toolbox, I want to import a feature class from a geodatabase into an ArcPro map and then symbolise that layer based on a lyrx file stored on disk. Here is a simplified version:

import arcpy, os 
aprx = arcpy.mp.ArcGISProject('CURRENT')
m = aprx.listMaps('*')[0]
outputWorkspace = r"C:\Path\To\MyProject.gdb"
arcpy.env.workspace = outputWorkspace 
out_fc = "fc_data"
out_fc_p = os.path.join(outputWorkspace, out_fc)
ref_lyrx = r"C:\Path\To\symbol_ref.lyrx"
m.addDataFromPath(out_fc_p)
out_fc_lyr = m.listLayers()[0]
arcpy.ApplySymbologyFromLayer_management(out_fc_lyr, ref_lyrx)

The script completes without error but no visible change is made to the symbology. Is this a bug? I've reviewed many similar questions but have been unable to resolve this.

Tags (2)
27 Replies
MartinHolleufer-Sørensen
New Contributor II

Thanks a lot for sharing this workaround, Michael. I don't know how many hours I would have had to spend to find the same combination/order of executing the different procedures....probably never would have found it....sometimes I feel like I keep running into limitations/bugs even though ArcGIS Pro is getting 4 years old....

Kind regards,

Martin

0 Kudos
DavidWilton
Occasional Contributor

Thanks Michael, this worked for me within my python toolbox. I'm just posting a slightly more complete sample which includes the ApplySymbologyFromLayer function

arcpy.AddMessage('Apply style')
current_project = arcpy.mp.ArcGISProject("CURRENT")
ags_map = current_project.listMaps()[0]

old_lyr = ags_map.addDataFromPath(file_path)
arcpy.management.ApplySymbologyFromLayer(old_lyr, r"C:\Temp\sourcelayer.lyrx", "VALUE_FIELD FIL_COLOUR FIL_COLOUR", "UPDATE")
arcpy.SaveToLayerFile_management(f.output_name, r"C:\Temp\templayer.lyr", "RELATIVE")
new_lyr_file = arcpy.mp.LayerFile(r"C:\Temp\templayer.lyrx")
new_lyr = new_lyr_file.listLayers()[0]
old_lyr_name = old_lyr.name
new_lyr.updateConnectionProperties(new_lyr.connectionProperties, old_lyr.connectionProperties)
new_lyr.name = old_lyr_name
new_lyr_file.save()
ags_map.insertLayer(old_lyr, new_lyr_file)
ags_map.removeLayer(old_lyr)
DavidWilton
Occasional Contributor

I asked to be attached to the bug BUG-000108497. It has been closed as a duplicate of https://my.esri.com/#/support/bugs/BUG-000106281 

This is strange because BUG-000106281 sites the pro SDK and was closed at 2.3.0. I have supplied a sample and will try to ensure a bug gets created and is not closed.

0 Kudos
LeandraGordon
Occasional Contributor II

See BUG-000108497: Running the Apply Layer Symbology tool as a script i..  , I tried the workaround (reopening the project ). Interestingly the first Apply layer command in the Python Toolbox does work (without reopening) but the other commands don't.

0 Kudos
DavidWilton
Occasional Contributor

I have added an updated to this case after receiving a response from Esri:

https://community.esri.com/thread/216962-apply-lyrx-file-symbology-via-python

0 Kudos
LeandraGordon
Occasional Contributor II

I finally worked out how to do it a Python Toolbox, here's an example:

 

In Init:

           # Spatial Data Layer
           param0 = arcpy.Parameter(
            displayName="Spatial Data Layer (SPATIALDATA_LYR)",
            name ="SPATIALDATA_LYR",
            datatype="GPFeatureLayer",
            parameterType="Derived",
            direction="Output")
        param0.value = "SPATIALDATA_LYR"
        # SMG (line) Layer
        param1 = arcpy.Parameter(
            displayName="SMG_LINE_LYR",
            name ="SMG_LINE_LYR",
            datatype="GPFeatureLayer",
            parameterType="Derived",
            direction="Output")
        param1.value = "SMG_LINE_LYR"
……...
    def execute(self, parameters, messages):
        """The source code of the tool."""
        arcpy.env.overwriteOutput=True
       
        # Script arguments      
        SPATIALDATA_LYR=parameters[0].valueAsText
        SMG_LINE_LYR= parameters[1].valueAsText
…..
        #LYRX File vars
        SPATIALDATA_LYRX =os.path.join(SEVENA_LYRX_DIR, "SPATIALDATA.lyrx")
        SMG_LYRX =os.path.join(SEVENA_LYRX_DIR, "SMG_NAME.lyrx")
…...
        arcpy.management.ApplySymbologyFromLayer(SPATIALDATA_LYR, SPATIALDATA_LYRX)
        arcpy.SetParameterAsText(0, SPATIALDATA_LYR)  #<--------------this!!!
       
        # SMG Line - getParameterInfo incl value, symb as os.path.join
        arcpy.management.ApplySymbologyFromLayer(SMG_LINE_LYR, SMG_LYRX, None, "UPDATE")
        arcpy.SetParameterAsText(1, SMG_LINE_LYR)
I have no idea why setting the parameter again makes it work, but it works.
0 Kudos
AndrewTFerguson
New Contributor

Hi all,

I'm new to Python but I think I may have (somewhat accidentally) found a workaround for those encountering this error within a Python Toolbox. I saved my output symbology template (.lyrx) in the same folder as my Python Toolbox. After defining my parameters in the getParameterInfo(self) method of the tool, I added the following 2 lines:

Fig 6.png

When I ran the tool, the correct symbology was applied to the output. This worked on my own laptop and my University's remote server, so I feel confident that it's a viable solution. 

The difference that I've noticed is that I applied they symbology in the getParameterInfo method rather than the execute method of the tool. 

Note: I ran the tool countless times (and received countless errors) over a few days when trying to update my output symbology. During my trial and error, I do recall receiving an "Attribute Error: 'str' has no attribute 'symbology'". I still don't understand why it "output_param.symbology" worked this time and not previous times, but like I said, I'm new to programming.

0 Kudos
JacobWeber
New Contributor

Here's a simple solution for ArcGIS Pro 3 python script tool results I got to work after struggling with this issue and it doesn't involve messing around with the script tool parameters mentioned above.  It creates a feature layer from a feature class, uses ApplySymbology, and then adds it to the map.  This assumes you have an existing layer file (lyrx) with the desired symbology:

arcpy.AddMessage("Adding results layers to the map")
aprx = arcpy.mp.ArcGISProject("CURRENT")
m = aprx.listMaps("Map")[0]
 
locAdds = (My results feature class)
Adds = arcpy.management.MakeFeatureLayer(locAdds, "Adds")
symbAdds = arcpy.management.ApplySymbologyFromLayer(Adds,r"C:\..\LayerFiles\Adds.lyrx").getOutput(0)
m.addLayer(symbAdds, "TOP")
0 Kudos