私はこの分野にもあまり強くありませんが、スニペットモジュールを変更し、非常に単純なタスク用のラッパーをいくつか作成しました。線要素を追加するだけの例があります。メインブロックの下の例では、ドキュメントのすぐ外側のレイアウトビューに三角形を形成しています。
このスクリプトを別の弧のある検索カーソルと組み合わせて使用して、個々の行とテキスト要素からレイアウト内にグラフィックテーブルを作成しますが、「単純な」例からすぐに離れてしまいます。以下のコードはかなり単純で、変更されたバージョンのスニペットを使用しています。
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)
編集:
@マット・ウィルキー
インポートの把握については、ここで、ArcObjectsモデル図を確認するか、.NET SDKヘルプドキュメントで特定のクラスまたはインターフェイスがどのネームスペースから呼び出されているかを確認する必要があります。継承のために、複数の名前空間を使用できる場合があります。
私はArcObjectsの専門家ではないので、CType()を使用していつキャストするかを理解するには、通常少し時間がかかります。このほとんどは、オンラインのサンプルから入手したものです。また、VB.NETの例の構文は、Pythonで行うことにより近いように見えますが、C#の例は、読みやすさの点で(私が理解できる場合)よりわかりやすくなっています。しかし、経験則として、私は通常、次の手順を実行します。
- 新しいCOMオブジェクト(通常はクラス)の変数を作成して、オブジェクトをインスタンス化します
- CTypeを使用してCOMオブジェクトをインターフェイスにキャストし、メソッドとプロパティへのアクセスを許可します。CTypeは、QueryInterface()を介してcomtypesインターフェイスポインターも返します。ポインタが返されると、そのプロパティとメソッドを操作できます。
適切な用語を使用しているかどうかわからない...私は主に一部のArcObjectsで「手を出して」いるPython開発者です...しかし、氷山の一角に触れただけです。
また、このヘルパー関数はすべての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]