Hello everybody,
I want to create an extent indicator by using arcpy. Here is an example how it should look like:
I know I have to use CIM for the solution but I have difficulties understanding the documentation.
Here is the code snippet I have tried out so far. As a result, no extent indicator is displayed at all. I have also swapped both map frames with each other and assigned ei_cim.sourceMapFrame = mf_main instead of ei_cim.sourceMapFrame = mf_main.name, but it doesn't help:
# Extent Indicator wird gesetzt
lyt_cim = lyt.getDefinition('V2')
ei_cim = arcpy.cim.CreateCIMObjectFromClassName('CIMExtentIndicator', 'V2')
ei_cim.sourceMapFrame = mf_main.name
ei_cim.extentIndicatorType = "Frame"
ei_cim.isVisible = True
ei_cim.name = "extent_indicator"
lyt_cim.elements[7].extentIndicators.insert(0, ei_cim)
lyt.setDefinition(lyt_cim)
lyt_cim.elements[7] is the second mapframe element.
What am I doing wrong?
Solved! Go to Solution.
@masa I tried your code on my Pro 3.3 machine, even with V2 and it worked. I would recommend trying on a more current build of Pro. There have been 5 new releases plus many patches since 2.8.
Jeff
This is actually something that could be accomplished pretty trivially using a map series if you have access to ArcPro. Just set up a series for the overview then link the second map to the primary map series and have it linked to the center.
@masa I believe the issue is that you don't have ei_cim.symbol or ei_cim.pointSymbol defined. It will require much more code to define these because multiple CIM classes are required to construct them from scratch. This is a classic example of where the Layout or MapFrame objects could use a helper function to insert an extent indicator, especially now that new layouts can be created. I would suggest adding an Esri Idea requesting this exact functionality. If you are not creating a layout in your script, it may be a lot easier to modify an already existing extent indicator.
Jeff - Layout and arcpy.mp teams.
I'll see if I can come up with a CIM solution later.
@masa here is some sample code to at least create the ei_cim.symbol. PointSymbol still needs to be defined if needed. Lines 6-26 below were added. I also altered how I'm finding the locator map frame in the CIM elements list instead of hard coding an index number (line 38-40).
p = arcpy.mp.ArcGISProject('current')
lyt = p.listLayouts()[0]
mf = lyt.listElements('MapFrame_Element', 'Main MF')[0]
lyt_cim = lyt.getDefinition('V3')
#Create Polygon Symbol with solid stroke outline and transparenent fill
polyStrokeRGBColor = arcpy.cim.CreateCIMObjectFromClassName('CIMRGBColor', 'V3')
polyStrokeRGBColor.values = [0, 0, 0, 100]
polySymLyr1 = arcpy.cim.CreateCIMObjectFromClassName('CIMSolidStroke', 'V3')
polySymLyr1.capStyle = "Round"
polySymLyr1.joinStyle = "Round"
polySymLyr1.width = 1
polySymLyr1.color = polyStrokeRGBColor
polyFillRGBColor = arcpy.cim.CreateCIMObjectFromClassName('CIMRGBColor', 'V3')
polyFillRGBColor.values = [0, 0, 0, 0]
polySymLyr2 = arcpy.cim.CreateCIMObjectFromClassName('CIMSolidFill', 'V3')
polySymLyr2.color = polyFillRGBColor
polySym = arcpy.cim.CreateCIMObjectFromClassName('CIMPolygonSymbol', 'V3')
polySym.symbolLayers = [polySymLyr1, polySymLyr2]
polySymRef = arcpy.cim.CreateCIMObjectFromClassName('CIMSymbolReference', 'V3')
polySymRef.symbol = polySym
#Create Extent indicator
ei_cim = arcpy.cim.CreateCIMObjectFromClassName('CIMExtentIndicator', 'V3')
ei_cim.sourceMapFrame = mf.name
ei_cim.extentIndicatorType = "Frame"
ei_cim.isVisible = True
ei_cim.name = "extent_indicator"
ei_cim.symbol = polySymRef
#ei_cim.pointSymbol = ptSymRef
for elm in lyt_cim.elements:
if elm.name == 'Locator MF':
elm.extentIndicators.insert(0, ei_cim)
#Set back to layer
lyt.setDefinition(lyt_cim)
Jeff
Thank you for your suggested solution!
Unfortunately, we are still working with version 2.8 at my company, which is why I also have to use version 2 for CIM. So I tried to adapt your solution to version 2, unfortunately without success.
Here is my adaptation:
version_cim = "V2"
lyt_cim = lyt.getDefinition(version_cim)
#Create Polygon Symbol with solid stroke outline and transparenent fill
polyStrokeRGBColor = arcpy.cim.CreateCIMObjectFromClassName('CIMRGBColor', version_cim)
polyStrokeRGBColor.values = [237, 122, 14, 100]
polySymLyr1 = arcpy.cim.CreateCIMObjectFromClassName('CIMSolidStroke', version_cim)
polySymLyr1.capStyle.LineCapStyle = 2
polySymLyr1.joinStyle.LineJoinStyle = 1
polySymLyr1.width = 2
polySymLyr1.color = polyStrokeRGBColor
polyFillRGBColor = arcpy.cim.CreateCIMObjectFromClassName('CIMRGBColor', version_cim)
polyFillRGBColor.values = [0, 0, 0, 0]
polySymLyr2 = arcpy.cim.CreateCIMObjectFromClassName('CIMSolidFill', version_cim)
polySymLyr2.color.values = polyFillRGBColor
polySym = arcpy.cim.CreateCIMObjectFromClassName('CIMPolygonSymbol', version_cim)
polySym.symbolLayers = [polySymLyr1, polySymLyr2]
polySymRef = arcpy.cim.CreateCIMObjectFromClassName('CIMSymbolReference', version_cim)
polySymRef.symbol = polySym
#Create Extent indicator
ei_cim = arcpy.cim.CreateCIMObjectFromClassName('CIMExtentIndicator', version_cim)
ei_cim.sourceMapFrame = mf_main.name
ei_cim.extentIndicatorType = "Frame"
ei_cim.isVisible = True
ei_cim.name = "extent_indicator"
ei_cim.symbol = polySymRef
for elm in lyt_cim.elements:
if elm.name == 'Map Frame Minimap':
elm.extentIndicators.insert(0, ei_cim)
#Set back to layer
lyt.setDefinition(lyt_cim)
In Debugger everything looks fine but in the corresponding APRX (which I save at the end of my code) nothing at all is displayed by an extent indicator.
I think I'm missing some little thing. Maybe you or someone else has an idea what the problem could be?
@masa I tried your code on my Pro 3.3 machine, even with V2 and it worked. I would recommend trying on a more current build of Pro. There have been 5 new releases plus many patches since 2.8.
Jeff
ok thanks for the feedback @JeffBarrette . Updating to a newer version does not work so quickly at my company. But then I assume that it is due to an outdated version. Thank you!