GraphicElement

摘要

图形元素是点、线和面等基础形状。 可通过 GraphicElement 对象访问属性和方法,这些属性和方法用于管理布局上或地图图形图层中的图形元素。

说明

GraphicElement 对象包含多种项目,例如点、线和添加到布局或图形图层中的区域形状。 Layout 对象上的 listElements 方法用于返回元素对象的 Python 列表。 然后,您必须遍历列表中的每个项目,或指定一个索引编号以引用特定元素。 要仅返回 GraphicElement 对象的列表,应对 element_type 参数使用 GRAPHIC_ELEMENT 常量。 还可以使用 wildcard 值,基于元素的 name 值对搜索进行进一步优化。 为每个元素提供一个唯一名称,以使元素可以通过 ArcPy 脚本引用。

使用以下方法之一创建图形元素:

  • 您可以使用 ArcGISProject 类上的 createGraphicElement 方法,通过提供 MultipointPointPolygonPolyline 几何来创建图形元素。
  • 您可以使用 ArcGISProject 类上的 createPredefinedGraphicElement 方法创建预配置的形状,例如圆形、椭圆或三角形。 可通过指定 Point 值或 Polygon 值来创建这些形状。
  • 可以使用 GraphicElement 对象的 clone 方法克隆现有图形元素。 此方法十分有用,因为在某些情况下,从现有元素开始操作会更加容易。 克隆元素时,请提供 suffix 值以使克隆的元素后续可以通过 listElements 方法使用通配符和相同的 suffix 值进行识别。 可以使用 delete 方法进一步修改或删除返回的元素列表。

创建图形元素时,可以使用两种基本方法指定要使用的几何。 第一种方法是传入定义图形元素的完整几何。 当您要创建点、多点或自定义区域形状时,此为必要步骤。 如要创建预定义形状(如矩形),则可以改为传入点几何并设置 elementWidthelementHeight 属性以完成所需的形状,而无需计算并传入创建几何所需的所有坐标。 点坐标将表示元素的 anchor 位置,将通过 elementPositionXelementPositionY 属性保留。

图形元素具有 getDefinitionsetDefinition 方法,可用于修改未向 GraphicElement 类暴露的附加属性。 有关详细信息,请参阅 Python CIM 访问帮助主题。

注:

ArcGIS Pro 3.2 之前的版本中,布局中的组元素 type 值为 GRAPHIC_ELEMENT。 从 ArcGIS Pro 3.2 版本开始,新 GroupElement 类的 type 值为 GROUP_ELEMENT。 图形元素继续支持 isGroup 以帮助实现向前兼容。

属性

属性说明数据类型
anchor
(只读)

返回表示当前锚点位置的以下字符串值之一。 要更改值,请使用 setAnchor 方法。

  • BOTTOM_LEFT_CORNER左下角位置
  • BOTTOM_MID_POINT底部中央位置
  • BOTTOM_RIGHT_CORNER右下角位置
  • CENTER_POINT中央位置
  • LEFT_MID_POINT左侧中央位置
  • RIGHT_MID_POINT右侧中央位置
  • TOP_LEFT_CORNER左上角位置
  • TOP_MID_POINT顶部中央位置
  • TOP_RIGHT_CORNER右上角位置
String
elementHeight
(可读写)

采用布局页面单位或地图单位的元素高度。

Double
elementPositionX
(可读写)

采用布局页面单位或地图单位的元素锚点位置的 x 位置。

Double
elementPositionY
(可读写)

采用布局页面单位或地图单位的元素锚点位置的 y 位置。

Double
elementRotation
(可读写)

元素旋转角度(以度为单位)。 正值将使方向顺时针旋转,负值将使方向逆时针旋转。

Double
elementWidth
(可读写)

采用布局页面单位或地图单位的元素宽度。

Double
isGroup
(只读)

如果元素是 True,则返回 GroupElement。 无法 clonedelete 组元素。

Boolean
locked
(可读写)

设置为 True 时,无法在布局或地图视图中以图形方式选择元素。

Boolean
longName
(只读)

元素的全名,包括组信息(如果存在)。 例如,在一个名称为 Point 的组元素中,名称为 Group Element 的元素将返回 Group Element\\PointlongName 值。 如果元素不在组中,则 longNamename 值相同。

String
name
(可读写)

元素的名称。 必须确保所有元素均具有唯一名称,因为这样可以通过在 Layout 对象的 listElements 函数中使用 wildcard 参数以唯一方式引用这些元素。

String
parentGroupElement
(只读)

如果元素在组中,则返回的值将为 GroupElement

GroupElement
type
(只读)

返回值 GRAPHIC_ELEMENT

String
visible
(可读写)

控制元素是否在布局或图形图层中可见。

Boolean

方法概述

方法说明
applyStyleItem (style_item)

applyStyleItem 方法可将样式项应用到图形元素上。

clone ({suffix})

提供了一种克隆页面布局中现有图形元素的机制。

delete ()

提供了一种删除页面布局中现有图形元素的机制。

getDefinition (cim_version)

返回图形元素的 CIM 定义。

setAnchor (anchor)

setAnchor 方法可控制 GraphicElement 的锚点位置。

setDefinition (definition_object)

设置图形元素的 CIM 定义。

方法

applyStyleItem (style_item)
参数说明数据类型
style_item

A reference to a StyleItem in a project.

StyleItem

当在 ArcGISProject 类上使用 listStyleItems 方法引用 StyleItem 时,style_class 参数必须是 POINTLINEPOLYGON。 由于图形元素支持多种几何类型,并且您可能在循环中遍历多个元素,因此您可能需要在应用样式之前确定几何类型。 下面的代码示例演示了此操作方法。 有关详细信息和代码示例,请参阅 StyleItem 帮助主题。

注:

在使用 applyStyleItem 方法之前,必须先将样式添加到工程中。 可以在 ArcGISProject 类上使用 updateStyles 方法添加样式。

以下脚本遍历布局中的图形元素,并使用 Python CIM 访问来确定图形元素的几何类型,然后再对每个元素应用样式项。

p = arcpy.mp.ArcGISProject('current')
lyt = p.listLayouts('*_Layout')[0]

poly_si = p.listStyleItems('ArcGIS 2D', 'Polygon', 'Park')[0]
line_si = p.listStyleItems('Favorites', 'Line', 'Trail')[0]
pt_si = p.listStyleItems('Favorites', 'Point', 'First Aid')[0]
multiPt_si = p.listStyleItems('Favorites', 'Point', 'Water')[0]
for elm in lyt.listElements('GRAPHIC_ELEMENT'):
  elm_cim = elm.getDefinition('V3')
  if isinstance(elm_cim.graphic, arcpy.cim.CIMGraphics.CIMPolygonGraphic):
    elm.applyStyleItem(poly_si)
  if isinstance(elm_cim.graphic, arcpy.cim.CIMGraphics.CIMLineGraphic):    
    elm.applyStyleItem(line_si)
  if isinstance(elm_cim.graphic, arcpy.cim.CIMGraphics.CIMPointGraphic):    
    elm.applyStyleItem(pt_si)
  if isinstance(elm_cim.graphic, arcpy.cim.CIMGraphics.CIMMultipointGraphic):    
    elm.applyStyleItem(multiPt_si)
clone ({suffix})
参数说明数据类型
suffix

用于标记每个新建图形元素的可选字符串。新元素的元素名为父项图形元素加上 suffix 值以及数值定序符。例如,如果父元素名称为 Linesuffix 值为 _copy,则新克隆的元素的名称为 Line_copyLine_copy_1Line_copy_2 等。如果未提供 suffix,则名称类似于 Line_1Line_2Line_3 等。

String

无法克隆分组的文本元素。所有分组元素都是图形元素类型。使用 GraphicElement 对象中的 isGroup 属性验证图形元素是否分组。

delete ()

可能需要删除现有或已克隆的图形元素。创建克隆元素时,可为克隆元素指定自定义 suffix,以便在对 Layout 对象上的 listElements 方法使用 wildcard 参数时可轻松找到这些元素。

getDefinition (cim_version)
参数说明数据类型
cim_version

A string that represents the major version of the CIM that will be used.

  • V2The 2.x version of the CIM will be used.
  • V3The 3.x version of the CIM will be used.
String
返回值
数据类型说明
Object

返回 GraphicElement 的 CIM 定义。

有关使用 CIM 和示例的详细信息,请参阅 Python CIM 访问

setAnchor (anchor)
参数说明数据类型
anchor

A string that specifies the location of the anchor position.

  • BOTTOM_LEFT_CORNERThe anchor will be set at the bottom left corner position.
  • BOTTOM_MID_POINTThe anchor will be set at the bottom center position.
  • BOTTOM_RIGHT_CORNERThe anchor will be set at the bottom right corner position.
  • CENTER_POINTThe anchor will be set at the center position.
  • LEFT_MID_POINTThe anchor will be set at the left center position.
  • RIGHT_MID_POINTThe anchor will be set at the right center position.
  • TOP_LEFT_CORNERThe anchor will be set at the top left corner position.
  • TOP_MID_POINTThe anchor will be set at the top center position.
  • TOP_RIGHT_CORNERThe anchor will be set at the top right corner position.
String

设置锚点位置非常有用,因为您可以控制元素在调整大小时的展开方式。 例如,图形元素的默认锚点位置为 BOTTOM_LEFT_CORNER。 如果将锚点位置更改为 TOP_RIGHT_CORNER,则更改 elementHeight 将使元素向下扩展,更改 elementWidth 将使元素向左扩展。

setDefinition (definition_object)
参数说明数据类型
definition_object

A modified CIM definition object originally retrieved using getDefinition.

Object

有关使用 CIM 和示例的详细信息,请参阅 Python CIM 访问

代码示例

GraphicElement 示例 1

以下脚本可使用新的锚点位置将名为 Grouped Graphics 的组元素移动到页面布局上的新位置,然后保存更改。

p = arcpy.mp.ArcGISProject('CURRENT')
lyt = p.listLayouts('Graphic*')[0]
elm = lyt.listElements('GROUP_ELEMENT', 'Grouped Graphics')[0]
elm.setAnchor('Center_Point')
elm.elementPositionX = 3.25
elm.elementPositionY = 9.5
GraphicElement 示例 2

以下脚本可在新布局中创建一个点图形元素。 然后,脚本可在新地图的图形图层中创建一个点图形元素。

p = arcpy.mp.ArcGISProject('current')

#Create a layout
lyt = p.createLayout(8.5, 11, 'INCH', 'New Layout with Point')

ptStyle = p.listStyleItems('ArcGIS 2D', 'Point', 'Star 1')[0]

#Construct a layout point graphic element using a default symbol
lyt_ptGra = p.createGraphicElement(lyt, arcpy.Point(4.125, 5.5),
                               ptStyle, 'ArcPy_Point')
#Optional - modify the symbol size via the CIM
lyt_ptGra_cim = lyt_ptGra.getDefinition('V3')
lyt_ptGra_cim.graphic.symbol.symbol.symbolLayers[0].size = 150
lyt_ptGra.setDefinition(lyt_ptGra_cim)

lyt.openView()


#Create a map (WGS 1984 Web Mecator) and graphics layer
m = p.createMap('New Map with Point', 'Map')
gl = m.createGraphicsLayer('New Graphics Layer')

#Construct a point in map space
map_ptGra = p.createGraphicElement(gl, arcpy.Point(-13681707, 5947924),
                               ptStyle, 'Olympia Capitol Building')

#Optional - modify the symbol size via the CIM
map_ptGra_cim = map_ptGra.getDefinition('V3')
map_ptGra_cim.graphic.symbol.symbol.symbolLayers[0].size = 25
map_ptGra.setDefinition(map_ptGra_cim)

m.openView()
GraphicElement 示例 3

以下脚本可在新布局中使用 48 个点构建多点图形元素,并使用 Python CIM 访问修改符号大小。

p = arcpy.mp.ArcGISProject('current')
lyt = p.createLayout(100, 100, 'CENTIMETER', 'X Marks the Spot')

#Construct 2 multi-point graphic elements using a system style item
mPtStyle = p.listStyleItems('ArcGIS 2D', 'Point', 'X Marker')[0]

x = 4; y = 4; z = 96
mPtCoords = []
for i in range(1, 25):
    xy = [x, y]
    xz = [x, z]
    mPtCoords.append(xy)
    mPtCoords.append(xz)
    x = x + 4
    y = y + 4
    z = z - 4
mPt = arcpy.Multipoint(arcpy.Array([arcpy.Point(*coords)
                                    for coords in mPtCoords]))
mPtGra = p.createGraphicElement(lyt, mPt, mPtStyle, name='ArcPy_MultiPt')

#Optional - modify the point symbol size via the CIM
mPtGra_cim = mPtGra.getDefinition('V3')
mPtGra_cim.graphic.symbol.symbol.symbolLayers[0].size = 75
mPtGra.setDefinition(mPtGra_cim)

lyt.openView()
GraphicElement 示例 4

以下脚本可在新布局中构建折线图形元素,并使用 Python CIM 访问修改其符号图层。

p = arcpy.mp.ArcGISProject('current')
lyt = p.createLayout(5, 3, 'INCH', 'New layout with line graphic')

#Construct a line graphic element using a sytem style item
lnStyle = p.listStyleItems('ArcGIS 2D', 'Line', 'Line with 2 Markers')[0]
plyLnCoords = [[1, 1.25], [2, 2], [3, 1], [4, 1.5]]
plyLn = arcpy.Polyline(arcpy.Array([arcpy.Point(*coords)
                                    for coords in plyLnCoords]))
lnGra = p.createGraphicElement(lyt, plyLn, lnStyle, 'ArcPy_Line')

#Optional - modify multiple line symbol layer properties via the CIM
lnGra_cim = lnGra.getDefinition('V3')
lnSym = lnGra_cim.graphic.symbol.symbol
lnSym.symbolLayers[0].size = 20
lnSym.symbolLayers[0].markerPlacement.offsetAlongLine = 60
lnSym.symbolLayers[0].markerPlacement.placementTemplate = [240]
lnSym.symbolLayers[1].size = 20
lnSym.symbolLayers[1].markerPlacement.offsetAlongLine = 180
lnSym.symbolLayers[1].markerPlacement.placementTemplate = [240]
lnSym.symbolLayers[2].effects[0].dashTemplate = [80, 40, 80, 40]
lnSym.symbolLayers[2].width = 4
lnGra.setDefinition(lnGra_cim)

lyt.openView()
GraphicElement 示例 5

以下脚本可使用 JSON 模板创建一个曲线 (arc) 和一个贝塞尔曲线几何。 该几何用于在新布局中创建两个图形元素。 可以选择性地使用 Python CIM 访问修改贝塞尔曲线的属性。 有关使用 JSON 创建几何对象的详细信息,请参阅几何对象

p = arcpy.mp.ArcGISProject('current')
lyt = p.createLayout(6, 3, 'INCH', 'New Layout with 2 curves')

#Construct a curve/arc graphic element using a default symbol
arcPath = {"curvePaths" : [[[3.5,1.25],{"c" : [[5,1.25],[4.25, 1.75]]}]]}
arc = arcpy.AsShape(arcPath, esri_json=True)
arcGra = p.createGraphicElement(lyt, arc, name='ArcPy_Arc')

#Construct a bezier curve graphic element using a system style item
curveStyle = p.listStyleItems('ArcGIS 2D', 'Line', 'Dashed 1 Long 1 Short')[0]
curvePath = {"curvePaths" : [[[1.25,1.25],
                              {"b" : [[3,1.5],[1.6875,2.75],[2.125,0]]}]]}
curve = arcpy.AsShape(curvePath, esri_json=True)
curveGra = p.createGraphicElement(lyt, curve, curveStyle, 'ArcPy_Curve')

#Optional - modify the bezier curve symbol layer properties via the CIM
curveGra_cim = curveGra.getDefinition('V3')
symLyr1 = curveGra_cim.graphic.symbol.symbol.symbolLayers[0]
symLyr1.width = 4
symLyr1.color.values = [255, 0, 0, 100]
symLyr1.effects[0].dashTemplate = [8, 8, 0.01, 8]
symLyr1.capStyle = 'Round'
curveGra.setDefinition(curveGra_cim)

lyt.openView()
GraphicElement 示例 6

以下脚本可在新布局中构建一个面图形元素,创建新地图,添加图层文件,然后将图层中的元素加载到新的图形图层中。

p = arcpy.mp.ArcGISProject('current')

#Create a layout
lyt = p.createLayout(8.5, 11, 'INCH', 'New Layout with Polygon')

#Construct a polygon graphic element using a system style item
polyStyle = p.listStyleItems('ArcGIS 2D', 'Polygon', 'Buffered Gradient')[0]

polyCoords = [[1, 1], [1, 10], [7.5, 10], [7.5, 9], [2, 9], [2, 6], [6.5, 6],
              [6.5, 5], [2, 5], [2, 2], [7.5, 2], [7.5, 1], [1, 1]]
poly = arcpy.Polygon(arcpy.Array([arcpy.Point(*coords)
                                  for coords in polyCoords]))
polyGra = p.createGraphicElement(lyt, poly, polyStyle, name='ArcPy_Polygon')

lyt.openView()


#Create a map, add a layer file and create a graphics layer
m = p.createMap('New Map with Feature Polygons', 'Map')
lyrFile = arcpy.mp.LayerFile(r"C:\Projects\GreatLakes\GreatLakes.lyrx")
m.addLayer(lyrFile)
lyr = m.listLayers('GreatLakes')[0]
gl = m.createGraphicsLayer('New Graphics Layer')

#Load polygon features into a map's graphics layer
#Caution - map graphics have limitations in terms of total size and number

for row in arcpy.da.SearchCursor(lyr, ["SHAPE@"]):
    featShp = row[0]
    p.createGraphicElement(gl, featShp, polyStyle)

m.openView()
GraphicElement 示例 7

以下脚本可在布局中创建两个预定义图形元素。 第一个图形元素使用包络矩形函数创建,第二个图形元素使用点位置,并使用 elementWidthelementHeight 属性重新调整大小。

def MakeRec_LL(llx, lly, w, h):
    xyRecList = [[llx, lly], [llx, lly+h], [llx+w,lly+h], [llx+w,lly], [llx,lly]]
    xyRecList = [[1,1],[1, 2], [2.75, 2], [2.75, 1], [1, 1]]
    array = arcpy.Array([arcpy.Point(*coords) for coords in xyRecList])
    rec = arcpy.Polygon(array)
    return rec

p = arcpy.mp.ArcGISProject('CURRENT')

#Create a layout
lyt = p.createLayout(6, 3, 'INCH', 'New Layout with Rectangles')

#Construct a pre-defined rectangle graphic element using a system style item
# and a rectangle function that takes x/y min/max and a width/height
# using the lower left corner as a start location

polyStyle = p.listStyleItems('ArcGIS 2D', 'Polygon', 'Orchard')[0]

p.createPredefinedGraphicElement(lyt, MakeRec_LL(1, 1, 1.75, 1), 'RECTANGLE',
                                 polyStyle, 'ArcPy_Rectangle_Env',
                                 lock_aspect_ratio=False)

#Construct the same element above using a point location
rec = p.createPredefinedGraphicElement(lyt, arcpy.Point(3, 1), 'RECTANGLE',
                                       polyStyle, 'ArcPy_Rectangle_Pt',
                                       lock_aspect_ratio=False)
rec.elementWidth = 1.75
rec.elementHeight = 1

lyt.openView()
GraphicElement 示例 8

以下脚本会为 10 个预定义形状中的每个形状创建一个面图形元素,将锚点设置为中心位置,然后使用 Python CIM 访问更新 Rounding 属性,该属性保存在与各个图形关联的自定义 propertySetItem 字典中。

p = arcpy.mp.ArcGISProject('current')
lyt = p.createLayout(8.5, 11, 'INCH', 'Predefined Shapes')

#A list of pre-defined shape key words
shapeList = ['Circle', 'Cloud', 'Cross', 'Ellipse', 'Half_Circle',
             'Rectangle', 'Right_Triangle', 'Rounded_Rectangle', 'Triangle', 'X']

x = 1.25
y = 9.5
for shape in shapeList:
    elm = p.createPredefinedGraphicElement(lyt, arcpy.Point(x, y), shape, name=f'ArcPy_{shape}_Pt')
    elm.setAnchor('Center_Point')
    if elm.elementWidth > elm.elementHeight:
        elm.elementWidth = 0.75
    else:
        elm.elementHeight = 0.75

    #Optional - use Python CIM Access to modify element rounding
    elm_cim = elm.getDefinition('V3')   
    attrbs = elm_cim.graphic.attributes
    attrbs['propertySetItems'] = ['Rounding', 50]  #Sets 50% rounding
    elm.setDefinition(elm_cim)

    y = y - 1

lyt.openView()
GraphicElement 示例 9

以下脚本可以基于地图中某个表的数据值构建图形表。 使用名为 vertLine 的垂直线、名为 horzLine 的水平线和名为 cellText 的文本元素制作布局。 每个元素使用相应的符号系统和文本属性进行创作。 元素锚点设置为左上角位置,文本元素的垂直和水平对齐设置为左上角对齐。

import arcpy
aprx = arcpy.mp.ArcGISProject(r"C:\Projects\YosemiteNP\Yosemite.aprx")

#Reference items in the project
m = aprx.listMaps("Yosemite National Park")[0]
lyr = m.listLayers("Valley_Pts")[0]
lyt = aprx.listLayouts("Points of Interest")[0]
horzLine = lyt.listElements("GRAPHIC_ELEMENT", "horzLine")[0]
vertLine = lyt.listElements("GRAPHIC_ELEMENT", "vertLine")[0]
tableText = lyt.listElements("TEXT_ELEMENT", "cellText")[0]

#Get/set information about the table
numRows = int(arcpy.GetCount_management(lyr).getOutput(0))
rowHeight = 0.2
fieldNames = ["COMPLEXID", "NAME"]
numColumns = len(fieldNames)
colWidth = 1.5

#Build graphic table lines based on upper left coordinate
#  set the proper size of the original, parent line, then clone it and position appropriately
upperX = 1.0
upperY = 5.0

#Vertical lines
vertLine.elementPositionX = upperX
vertLine.elementPositionY = upperY
vertLine.elementHeight =  (rowHeight * numRows) + rowHeight #extra line for column names

x = upperX
for vert in range(1, numColumns+1):
  x = x + colWidth
  vert_clone = vertLine.clone("_clone")
  vert_clone.elementPositionX = x

#Horizontal lines
horzLine.elementPositionX = upperX
horzLine.elementPositionY = upperY
horzLine.elementWidth = numColumns * colWidth

y = upperY - rowHeight
for horz in range(1, numRows +2 ):  #need to accommodate the extra line for field names
  temp_horz = horzLine.clone("_clone")
  temp_horz.elementPositionY = y
  y = y - rowHeight

#Place text column names
tableText.elementPositionX = upperX + 0.05 #slight offset
tableText.elementPositionY = upperY
tableText.text = fieldNames[0]
accumWidth = colWidth
for field in range(1, numColumns):
  newFieldTxt = tableText.clone("_clone")
  newFieldTxt.text = fieldNames[field]
  newFieldTxt.elementPositionX = newFieldTxt.elementPositionX + accumWidth
  accumWidth = accumWidth + colWidth

#Create text elements based on values from the table
table = arcpy.SearchCursor(lyr.dataSource)
y = upperY - rowHeight
for row in table:
  x = upperX + 0.05 #slight offset
  try:   
    for field in fieldNames:
      newCellTxt = tableText.clone("_clone")
      newCellTxt.text = row.getValue(field)
      newCellTxt.elementPositionX = x
      newCellTxt.elementPositionY = y
      accumWidth = accumWidth + colWidth
      x = x + colWidth
    y = y - rowHeight
  except:
    print("Invalid value assignment")

#Export to PDF and delete cloned elements
lyt.exportToPDF(r"C:\Temp\test.pdf")

for elm in lyt.listElements(wildcard="_clone"):
  elm.delete()
del aprx