Tôi cũng không mạnh lắm trong lĩnh vực này, nhưng tôi đã sửa đổi mô-đun Snippets và đã thực hiện một vài hàm bao cho các tác vụ rất đơn giản. Tôi có một ví dụ về việc chỉ thêm các yếu tố dòng. Ví dụ ở dưới khối chính tạo thành một hình tam giác cho khung nhìn bố cục ngay bên ngoài tài liệu.
Tôi sử dụng tập lệnh này kết hợp với các con trỏ tìm kiếm khác và phức tạp để tạo các bảng đồ họa trong bố cục từ các dòng riêng lẻ và các thành phần văn bản, nhưng điều đó nhanh chóng di chuyển ra khỏi ví dụ "đơn giản". Mã dưới đây khá đơn giản và sử dụng một phiên bản sửa đổi của đoạn trích:
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)
Biên tập:
@matt wilkie
Đối với việc tìm ra các mục nhập, đó là nơi bạn sẽ phải xem qua Sơ đồ mô hình ArcObjects hoặc xem không gian tên mà một Lớp hoặc Giao diện cụ thể đang được gọi từ trong tài liệu trợ giúp .NET SDK. Trong một số trường hợp, nhiều không gian tên có thể được sử dụng do kế thừa.
Tôi không phải là chuyên gia về ArcObjects, vì vậy tôi thường phải mất một thời gian để tìm ra khi nào nên thực hiện mọi thứ với CType (). Hầu hết điều này, tôi đã chọn từ các mẫu trực tuyến. Ngoài ra, cú pháp từ các ví dụ VB.NET dường như gần với những gì bạn làm trong Python, nhưng các ví dụ C # có ý nghĩa hơn đối với tôi về khả năng đọc (nếu điều đó có ý nghĩa gì). Nhưng, theo nguyên tắc thông thường, tôi thường theo dõi các bước sau:
- Tạo một biến cho một đối tượng COM mới (thường là một lớp) để khởi tạo một đối tượng
- Sử dụng CType để truyền đối tượng COM sang (các) giao diện để cho phép truy cập vào các phương thức và các chương trình. CType cũng sẽ trả về Con trỏ Giao diện comtypes thông qua QueryInterface (). Khi con trỏ được trả về, bạn có thể tương tác với các thuộc tính và phương thức của nó.
Không chắc chắn liệu tôi có sử dụng thuật ngữ thích hợp hay không ... Tôi chủ yếu là một nhà phát triển Python "vọc" trong một số ArcObjects ... Mặc dù vậy, tôi chỉ chạm vào phần nổi của tảng băng trôi.
Ngoài ra, hàm trợ giúp này sẽ tải tất cả các Thư viện đối tượng 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]