Nemmeno io sono molto forte in quest'area, ma ho modificato il modulo Snippets e ho creato un paio di wrapper per compiti molto semplici. Ho un esempio dell'aggiunta di elementi di linea. L'esempio sotto il blocco principale forma un triangolo per la vista del layout appena fuori dal documento.
Uso questo script insieme ad altri cursori di ricerca arcpy per creare tabelle grafiche nel layout da singole linee ed elementi di testo, ma questo si allontana rapidamente dall'esempio "semplice". Il codice seguente è abbastanza semplice e utilizza una versione modificata degli snippet:
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)
Modificare:
@matt wilkie
Per quanto riguarda la determinazione delle importazioni, è qui che dovrete guardare i diagrammi del modello ArcObjects o vedere da quale spazio dei nomi viene richiamata una determinata classe o interfaccia nei documenti della guida di .NET SDK. In alcuni casi è possibile utilizzare più di uno spazio dei nomi a causa dell'ereditarietà.
Non sono un esperto di ArcObjects, quindi di solito mi ci vuole un po 'per capire quando lanciare le cose con CType (). Gran parte di questo, ho raccolto da campioni online. Inoltre, la sintassi degli esempi VB.NET sembra essere più vicina a ciò che fai in Python, ma gli esempi C # hanno più senso per me in termini di leggibilità (se questo ha un senso). Ma, di regola, di solito seguo questi passaggi:
- Creare una variabile per un nuovo oggetto COM (in genere una classe) per creare un'istanza di un oggetto
- Utilizzare CType per trasmettere l'oggetto COM a un'interfaccia (s) per consentire l'accesso a metodi e proprietà. CType restituirà anche il puntatore a interfaccia dei tipi tramite QueryInterface (). Una volta restituito il puntatore, è quindi possibile interagire con le sue proprietà e metodi.
Non sono sicuro se sto usando la terminologia corretta o no ... Sono principalmente uno sviluppatore Python che "diletta" in alcuni ArcObjects ... Tuttavia ho solo toccato la punta dell'iceberg.
Inoltre, questa funzione di supporto caricherà tutte le librerie di oggetti 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]