Também não sou muito forte nessa área, mas modifiquei o módulo Snippets e criei alguns wrappers para tarefas muito simples. Eu tenho um exemplo de apenas adicionar elementos de linha. O exemplo no bloco principal forma um triângulo para a visualização do layout, fora do documento.
Eu uso esse script em conjunto com outros cursores de pesquisa e arcpy para criar tabelas gráficas no layout a partir de linhas individuais e elementos de texto, mas isso rapidamente se afasta do exemplo "simples". O código abaixo é bastante simples e usa uma versão modificada dos trechos:
from snippets import *
def add_line(pApp=None, name='Line', x=None, y=None, end_x=None, end_y=None,
x_len=0, y_len=0, anchor=0, view='layout'):
'''adds a line to an ArcMap Document
Required:
pApp -- reference to either open ArcMap document or path on disk
name -- name of line element
Optional:
x -- start x coordinate, if none, middle of the extent will be used (data view)
y -- start y coordinate, if none, middle of the extent will be used (data view)
end_x -- end x coordinate, if making straight lines use x_len
end_y -- end y coordinate, if making straight lines use y_len
x_len -- length of line in east/west direction
y_len -- length of line in north/south direction
anchor -- anchor point for line element
view -- choose view for text element (layout|data)
Anchor Points:
esriTopLeftCorner 0 Anchor to the top left corner.
esriTopMidPoint 1 Anchor to the top mid point.
esriTopRightCorner 2 Anchor to the top right corner.
esriLeftMidPoint 3 Anchor to the left mid point.
esriCenterPoint 4 Anchor to the center point.
esriRightMidPoint 5 Anchor to the right mid point.
esriBottomLeftCorner 6 Anchor to the bottom left corner.
esriBottomMidPoint 7 Anchor to the bottom mid point.
esriBottomRightCorner 8 Anchor to the botton right corner.
'''
GetDesktopModules()
import comtypes.gen.esriFramework as esriFramework
import comtypes.gen.esriArcMapUI as esriArcMapUI
import comtypes.gen.esriSystem as esriSystem
import comtypes.gen.esriGeometry as esriGeometry
import comtypes.gen.esriCarto as esriCarto
import comtypes.gen.esriDisplay as esriDisplay
import comtypes.gen.stdole as stdole
# set mxd
if not pApp:
pApp = GetApp()
pDoc = pApp.Document
pMxDoc = CType(pDoc, esriArcMapUI.IMxDocument)
pMap = pMxDoc.FocusMap
pMapL = pMap
if view.lower() == 'layout':
pMapL = pMxDoc.PageLayout
pAV = CType(pMapL, esriCarto.IActiveView)
pSD = pAV.ScreenDisplay
# set coords for elment
pFact = CType(pApp, esriFramework.IObjectFactory)
if view.lower() == 'data':
pEnv = pAV.Extent
if x == None:
x = (pEnv.XMin + pEnv.XMax) / 2
if y == None:
y = (pEnv.YMin + pEnv.YMax) / 2
else:
# default layout position, move off page
if x == None: x = -4
if y == None: y = 4
# from point
pUnk_pt = pFact.Create(CLSID(esriGeometry.Point))
pPt = CType(pUnk_pt, esriGeometry.IPoint)
pPt.PutCoords(x, y)
# to point
pUnk_pt2 = pFact.Create(CLSID(esriGeometry.Point))
pPt2 = CType(pUnk_pt2, esriGeometry.IPoint)
if x_len or y_len:
pPt2.PutCoords(x + x_len, y + y_len)
elif end_x or end_y:
pPt2.PutCoords(end_x, end_y)
# line (from point - to point)
pUnk_line = pFact.Create(CLSID(esriGeometry.Polyline))
pLg = CType(pUnk_line, esriGeometry.IPolyline)
pLg.FromPoint = pPt
pLg.ToPoint = pPt2
# preset color according to RGB values
pUnk_color = pFact.Create(CLSID(esriDisplay.RgbColor))
pColor = CType(pUnk_color, esriDisplay.IRgbColor)
pColor.Red, pColor.Green, pColor.Blue = (0,0,0) #black line
# set line properties
pUnk_line = pFact.Create(CLSID(esriDisplay.SimpleLineSymbol))
pLineSymbol = CType(pUnk_line, esriDisplay.ISimpleLineSymbol)
pLineSymbol.Color = pColor
# create the actual element
pUnk_elm = pFact.Create(CLSID(esriCarto.LineElement))
pLineElement = CType(pUnk_elm, esriCarto.ILineElement)
pLineElement.Symbol = pLineSymbol
pElement = CType(pLineElement, esriCarto.IElement)
# elm properties
pElmProp = CType(pElement, esriCarto.IElementProperties3)
pElmProp.Name = name
pElmProp.AnchorPoint = esriCarto.esriAnchorPointEnum(anchor)
pElement.Geometry = pLg
# add to map
pGC = CType(pMapL, esriCarto.IGraphicsContainer)
pGC.AddElement(pElement, 0)
pGCSel = CType(pMapL, esriCarto.IGraphicsContainerSelect)
pGCSel.SelectElement(pElement)
iOpt = esriCarto.esriViewGraphics + \
esriCarto.esriViewGraphicSelection
pAV.PartialRefresh(iOpt, None, None)
return pElement
if __name__ == '__main__':
# testing (make a triangle)
add_line(name='hypot', end_x=-2, end_y=2, anchor=3)
add_line(name='vertLine', y_len=-2, anchor=1)
add_line(name='bottom', y=2, end_x=-2, end_y=2)
Editar:
@matt wilkie
Quanto a descobrir as importações, é aí que você terá que examinar os diagramas de modelos do ArcObjects ou ver em qual namespace uma classe ou interface específica está sendo chamada nos documentos de ajuda do .NET SDK. Em alguns casos, mais de um espaço para nome pode ser usado devido à herança.
Como não sou especialista em ArcObjects, normalmente levo um tempo para descobrir quando lançar as coisas com CType (). A maior parte disso, eu peguei de amostras online. Além disso, a sintaxe dos exemplos do VB.NET parece estar mais próxima do que você faz no Python, mas os exemplos em C # fazem mais sentido para mim em termos de legibilidade (se isso faz algum sentido). Mas, como regra geral, eu costumo seguir estas etapas:
- Crie uma variável para um novo objeto COM (geralmente uma classe) para instanciar um objeto
- Use CType para converter o objeto COM em uma interface para permitir o acesso a métodos e propriedades. CType também retornará o ponteiro de interface comtypes via QueryInterface (). Depois que o ponteiro é retornado, você pode interagir com suas propriedades e métodos.
Não tenho certeza se estou usando a terminologia adequada ou não ... Eu sou principalmente um desenvolvedor Python que "brinca" em alguns ArcObjects ... Mas apenas toquei a ponta do iceberg.
Além disso, essa função auxiliar carregará todas as bibliotecas de objetos do ArcObjects (.olb):
def load_all():
'''loads all object libraries'''
from comtypes.client import GetModule
mods = glob.glob(os.path.join(GetLibPath(), '*.olb'))
for mod in mods:
GetModule(mod)
return
def GetLibPath():
'''Reference to com directory which houses ArcObjects
Ojbect Libraries (*.OLB)'''
return glob.glob(os.path.join(arcpy.GetInstallInfo()['InstallDir'], 'com'))[0]