1. 为什么使用 Python?
2. 关于地理处理对象
3. 使用 ArcObjects
在 Python 中要调用基于 COM 的 ArcObjects 就得使用 comtypes 模块。从以下地址下载:http://sourceforge.net/projects/comtypes/
读取和导入模块
def GetLibPath(): ## 返回 ArcGIS 的 COM 路径,比如: "C:/Program Files/ArcGIS/com/" import _winreg keyESRI = _winreg.OpenKey(_winreg.HKEY_LOCAL_MACHINE, "SOFTWARE//ESRI//ArcGIS") return _winreg.QueryValueEx(keyESRI, "InstallDir")[0] + "com//" def GetModule(sModuleName): import comtypes from comtypes.client import GetModule sLibPath = GetLibPath() GetModule(sLibPath + sModuleName) # 主程序中就可以直接使用 GetModule 来载入需要的库 GetModule("esriGeometry.olb") import comtypes.gen.esriGeometry as esriGeometry # 或者 from comtypes.gen.esriGeometry import Point, IPoint # 不推荐 import *
创建和对象类型转换
def NewObj(MyClass, MyInterface): from comtypes.client import CreateObject try: ptr = CreateObject(MyClass, interface=MyInterface) return ptr except: return None def CType(obj, interface): try: newobj = obj.QueryInterface(interface) return newobj except: return None def CLSID(MyClass): return str(MyClass._reg_clsid_)
独立运行程序的许可
pInit = NewObj(esriSystem.AoInitialize, esriSystem.IAoInitialize) # 另外 10.0 之后,初始化许可之前,必须选择版本。详见下文。 eProduct = esriSystem.esriLicenseProductCodeArcEditor licenseStatus = pInit.IsProductCodeAvailable(eProduct) if licenseStatus == esriSystem.esriLicenseAvailable: licenseStatus = pInit.Initialize(eProduct) return (licenseStatus == esriSystem.esriLicenseCheckedOut) # 或者使用地理处理对象来代替 import arcgisscripting gp = arcgisscripting.create(9.3) gp.setproduct("ArcEditor")
从外部寻找一个已运行的 ArcGIS 实例
if not (app == "ArcMap" or app == "ArcCatalog"): return None pAppROT = NewObj(esriFramework.AppROT, esriFramework.IAppROT) iCount = pAppROT.Count if iCount == 0: return None for i in range(iCount): pApp = pAppROT.Item(i) if app == "ArcCatalog": if CType(pApp, esriCatalogUI.IGxApplication): return pApp continue if CType(pApp, esriArcMapUI.IMxApplication): return pApp return None
获取已选择的图元
pApp = GetApp() # ...其他一些操作 pDoc = pApp.Document pMxDoc = CType(pDoc, esriArcMapUI.IMxDocument) pMap = pMxDoc.FocusMap pFeatSel = pMap.FeatureSelection pEnumFeat = CType(pFeatSel, esriGeoDatabase.IEnumFeature) pEnumFeat.Reset() pFeat = pEnumFeat.Next() if not pFeat: print "No selection found." return pShape = pFeat.ShapeCopy eType = pShape.GeometryType if eType == esriGeometry.esriGeometryPoint: print "Geometry type = Point" # ...其他一些操作
使用 IObjectFactory 创建会话对象。 获取了 ArcGIS 程序的实例之后,就可以使用 IObjectFactory 创建新的对象
pApp = GetApp() pFact = CType(pApp, esriFramework.IObjectFactory) pUnk = pFact.Create(CLSID(esriCarto.TextElement)) pTextElement = CType(pUnk, esriCarto.ITextElement)
在 10.0 中,可以使用 ArcGIS 程序里面内置的 Python 命令行运行脚本。另外,也可以使用 AppRef 获得进程的句柄
pApp = NewObj(esriFramework.AppRef, esriFramework.IApplication)
UID 和枚举
pApp = GetApp() # ...其他一些操作 pID = NewObj(esriSystem.UID, esriSystem.IUID) pID.Value = CLSID(esriEditor.Editor) pExt = pApp.FindExtensionByCLSID(pID) pEditor = CType(pExt, esriEditor.IEditor) if pEditor.EditState == esriEditor.esriStateEditing: pWS = pEditor.EditWorkspace pDS = CType(pWS, esriGeoDatabase.IDataset) print "Workspace name: " + pDS.BrowseName print "Workspace category: " + pDS.Category
同样,也可以返回多个值
iEdgeEID, bReverse, oWeight = pForwardStar.QueryAdjacentEdge(i)
空值、IsNull 和 None。 支持使用 None 作为参数中的空值
iOpt = esriCarto.esriViewGraphics + esriCarto.esriViewGraphicSelection pActiveView.PartialRefresh(iOpt, None, None)
通过布尔测试来判断是否空值,使用 is None 来判断是否数据库中的空值(图元属性的空值)
pCursor = pTab.Search(pQF, True) pRow = pCursor.NextRow() if not pRow: print "Query returned no rows" return Val = pRow.Value(pTab.FindField(sFieldName)) if Val is None: print "Null value"
写入和检索属性 (最好是使用地理处理工具来创建表以及增加字段)
pNewField = NewObj(esriGeoDatabase.Field, esriGeoDatabase.IField) pFieldEdit = CType(pNewField, esriGeoDatabase.IFieldEdit) pFieldEdit._Name = "LUMBERJACK" pFieldEdit._Type = esriGeoDatabase.esriFieldTypeString pFieldEdit._Length = 50 pFieldsEdit._Field[1] = pNewField pOutTable = pFWS.CreateTable(sTableName, pOutFields, None, None, "") iField = pOutTable.FindField("LUMBERJACK") print "'LUMBERJACK' field index = ", iField pRow = pOutTable.CreateRow() pRow.Value[iField] = "I sleep all night and I work all day" pRow.Store()
创建一个用于 ArcMap 或 ArcCatalog 的 COM 对象
其他一些建议
本文翻译自 Mark Cederholm 的 PDF:Using ArcObjects in Python
示例代码:http://www.pierssen.com/arcgis10/python.htm