Select to view content in your preferred language

Vary Symbology By Rotation accessible by ArcPy?

1240
3
09-19-2018 06:08 AM
Status: Implemented
Labels (1)
ZacharyKlaas
Emerging Contributor

Basically my issue is that ArcGIS Pro rotates symbols very nicely through its GUI according to the values coming from an attribute table variable (Vary symbology by rotation, one of the specific Vary symbology by attribute options), but that I am having difficulty getting ArcPy to do the same thing automatically for the user.  I'm writing a script to process thousands of ship locations and all I want is to turn the ships the direction they are facing via a variable on what the ship heading is, something I can do with manually in ten seconds.

 

This comes from the discussion concerning an ArcPy question I had (Let's try this another way: Is there any way in ArcPy to reproduce the "Vary symbology by rotation" ...

 

Can ArcPy make this Vary symbology by rotation functionality accessible?

3 Comments
KoryKramer

Are you able to save a lyrx file containing the rotation definition and then apply symbology from the lyrx through your Python script?

KeithAddison1

I too wish python was an option when using vary symbology by rotation.  I devote enough of my brain already to arbitrary syntax.

JeffBarrette
Status changed to: Implemented

We know this is a long time coming.  We want to add helper functions to our API but the priority is lower than many other capabilities so we hope this serves as a solution.  It uses Python CIM Access.

Sample 1: Vary Symbology using Rotation

The following script will rotate each feature in a point feature class using VarySymbology By Attribute based on an attribute that controls ROTATION.  If the visual variable already exists, it toggles the rotation type each time the script is run.

# Create / Modify point layer symbol to Vary Symbology by Attribute using Rotation

# The script will effectively change the symbology each time it runs:
#   First, if visual variables don't exist, it create a one using rotation.
#   Second, if it does exist, it reverses the rotation type each time.


p = arcpy.mp.ArcGISProject('current')
m = p.listMaps('VarySymByAttr - Rotation')[0]
l = m.listLayers('Cities - No Rotation')[0]
l_cim = l.getDefinition('V3')

if len(l_cim.renderer.visualVariables) == 0:
    print('Visual Variable DOES NOT exist ... creating with default values')
    XYvvInfo = arcpy.cim.CreateCIMObjectFromClassName('CIMVisualVariableInfo', 'V3')
    XYvvInfo.randomMax = 360
    XYvvInfo.visualVariableInfoType = None

    ZexpInfo = arcpy.cim.CreateCIMObjectFromClassName('CIMExpressionInfo', 'V3')
    ZexpInfo.title = "Custom"
    ZexpInfo.expression = "$feature.HAWN_PI"
    ZexpInfo.returnType = "Default"

    ZvvInfo = arcpy.cim.CreateCIMObjectFromClassName('CIMVisualVariableInfo', 'V3')
    ZvvInfo.randomMax = 360
    ZvvInfo.visualVariableInfoType = "Expression"
    ZvvInfo.valueExpressionInfo = ZexpInfo
    
    
    rvv = arcpy.cim.CreateCIMObjectFromClassName('CIMRotationVisualVariable', 'V3')
    rvv.visualVariableInfoX = XYvvInfo
    rvv.visualVariableInfoY = XYvvInfo
    rvv.visualVariableInfoZ = ZvvInfo
    rvv.rotationTypeZ = "Arithmetic"

    l_cim.renderer.visualVariables = [rvv]
    l.setDefinition(l_cim)
else:
    print('Visual Variable already DOES exist ... modifying rotation type')
    for vv in l_cim.renderer.visualVariables:
        if isinstance(vv, arcpy.cim.CIMSymbolizers.CIMRotationVisualVariable):
            if vv.rotationTypeZ == "Arithmetic":
                vv.rotationTypeZ = 'Geographic'
            else:
                vv.rotationTypeZ = 'Arithmetic'
            l.setDefinition(l_cim)

 

Sample 2: Vary Symbology using Transparency

The following script will modify the transparency for each feature in a polygon feature class using VarySymbology By Attribute based on an attribute that controls TRANSPARENCY.  If the visual variable already exists, it changes the transparency values.

#Create / Modify polygon layer symbol to Vary Symbology by Attribute using Transparency

# The script will effectively change the symbology 3 times:
#   First, if visualvariables don't exist,
#   Second, if the transparency values are default, change
#   Third, if they are not default change to something else.


p = arcpy.mp.ArcGISProject('current')
m = p.listMaps('VarySymByAttr - Transparency')[0]
l = m.listLayers('States*')[0]
l_cim = l.getDefinition('V3')

#Get min/max values of renderer
minValue = l.symbology.renderer.lowerBound
maxValue = l.symbology.renderer.classBreaks[-1].upperBound

if len(l_cim.renderer.visualVariables) == 0:
    print('Visual Variable DOES NOT exist ... creating with default values')
    ai = arcpy.cim.CreateCIMObjectFromClassName('CIMVisualVariableAuthoringInfo', 'V3')
    ai.minSliderValue = minValue
    ai.maxSliderValue = maxValue
    ai.heading = 'POP2000'

    tvv = arcpy.cim.CreateCIMObjectFromClassName('CIMTransparencyVisualVariable', 'V3')
    tvv.authoringInfo = ai
    tvv.field = 'POP2000'
    tvv.transparencyValues = [70, 30]
    tvv.dataValues = [minValue, maxValue]
    tvv.normalizationType = "Nothing"
    tvv.valueExpressionInfo = None

    l_cim.renderer.visualVariables = [tvv]
    l.setDefinition(l_cim)
else:
    print('Visual Variable already DOES exist ... modifying transparencyValues')
    if l_cim.renderer.visualVariables[0].transparencyValues == [70, 30]:
        l_cim.renderer.visualVariables[0].transparencyValues = [80, 0]
    else:
        l_cim.renderer.visualVariables[0].transparencyValues = [50, 0]
    l.setDefinition(l_cim) 

Jeff - arcpy.mp and Layout (SDK) teams