In C:\Python27\ArcGIS10.1\Lib\site-packages\comtypes
Delete automation.pyc, automation.pyo, safearray.pyc, safearray.pyo
Edit automation.py
Add the following entry to the _ctype_to_vartype dictionary (line 794):
POINTER(BSTR): VT_BYREF|VT_BSTR,
At the Python prompt:
>>> from comtypes.client import GetModule
>>> GetModule("c:/program files/arcgis/desktop10.1/com/esriArcMapUI.olb")
TIP: If loading one or modules fails, delete all files in the comtypes/gen folder before trying again.
# ConvertAnnotationToPoygons.py # Updated for python ArcGIS 10.1 using comtypes # Import Modules import arcpy from arcpy import env import os import sys import comtypes.client import comtypes.gen.esriSystem as esriSystem import comtypes.gen.esriGeometry as esriGeometry import comtypes.gen.esriGeoDatabase as esriGeoDatabase import comtypes.gen.esriGeoprocessing as esriGeoprocessing import comtypes.gen.esriArcMapUI as esriArcMapUI import comtypes.gen.esriCarto as esriCarto import comtypes.gen.esriDisplay as esriDisplay import comtypes.gen.esriFramework as esriFramework import comtypes.gen.esriDataSourcesFile as esriDataSourcesGDB 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 GetApp(): """Get a hook into the current session of ArcMap""" pAppROT = NewObj(esriFramework.AppROT, esriFramework.IAppROT) if pAppROT is not None: iCount = pAppROT.Count if iCount == 0: print 'No ArcGIS application currently running. Terminating ...' return None for i in range(iCount): pApp = pAppROT.Item(i) #returns IApplication on AppRef print pApp.Name if pApp.Name == 'ArcMap': print "ArcMap found" pDoc = pApp.Document print pDoc.Title if pDoc.Title == "untitled.mxd" or pDoc.Title == "Untitled": return pApp print 'No ArcMap session is running at this time.' print "No AppROT found" print "Failed" return None def AnnotoPoly(): #USER SETTINGS #SET these variables for your individual case FDOLayerNum = 0 #Set annotation layer here (zero-based: 0 is first layer in TOC) FLayerNum = 1 #Set empty feature layer here (zero-based: 1 is second layer in TOC) OutputDPI = 1200 #Highest DPI of your final output device(s) ScreenResolution = 96 #Resolution of your monitor FinalOutputScale = 24000 #Final scale that your map will be printed with pApp = GetApp() pDoc = pApp.Document pMxDoc = CType(pDoc, esriArcMapUI.IMxDocument) pMap = pMxDoc.FocusMap pActiveView = CType(pMap, esriCarto.IActiveView) pActiveView.Refresh() pScreenDisplay = pActiveView.ScreenDisplay pDisplayTransform = pScreenDisplay.DisplayTransformation pFLayer = pMap.Layer(FLayerNum) pFL = CType(pFLayer, esriCarto.IFeatureLayer) pFClass = CType(pFL.FeatureClass, esriGeoDatabase.IFeatureClass) pClass = pMap.Layer(FDOLayerNum) pAnnoClass = CType(pClass,esriCarto.IFeatureLayer) pAnnoClass = pAnnoClass.FeatureClass pAnnoClass = CType(pAnnoClass.Extension,esriCarto.IAnnoClass) ReferenceScale = pMap.ReferenceScale MapScale = pMap.MapScale OptimumScale = float(ScreenResolution) / OutputDPI * FinalOutputScale / 2 AnnoScaleFactor = float(pAnnoClass.ReferenceScale / OptimumScale) pFDOGraphicsLayer = pMap.Layer(FDOLayerNum) pFDOGraphicsRead = CType(pFDOGraphicsLayer, esriCarto.IFDOGraphicsLayerRead) pMap.ReferenceScale = 0 pMap.MapScale = OptimumScale # Generate Annotation Graphics pFDOGraphicsRead.StartGeneratingGraphics(None, pScreenDisplay, True, True, False) pAnnoElement = pFDOGraphicsRead.NextGraphic while pAnnoElement: pTextElement = CType(pAnnoElement, esriCarto.ITextElement) pTextSymbol = pTextElement.Symbol #Temporarily change text symbol's size TempTextSize = pTextSymbol.Size pTextSymbol.Size = float(TempTextSize) * AnnoScaleFactor pTextQuery = CType(pTextSymbol, esriDisplay.IQueryGeometry) pTextPointGeo = CType(pAnnoElement.Geometry, esriGeometry.IGeometry) pScreenDisplay.StartDrawing(pScreenDisplay.WindowDC, pScreenDisplay.ActiveCache) pPolygon = CType(pTextQuery.GetGeometry(pScreenDisplay.WindowDC, pDisplayTransform, pTextPointGeo), esriGeometry.IPolygon) #Ensure geometry is suitable for a feature (sorts inner/outter rings) pTopoOperator2 = CType(pPolygon, esriGeometry.ITopologicalOperator2) pTopoOperator2.IsKnowSimple_2 = False pPolygon.SimplifyPreserveFromTo() pScreenDisplay.FinishDrawing #Restore textsymbol size pTextSymbol.Size = TempTextSize pFeature = CType(pFClass.CreateFeature(), esriGeoDatabase.IFeature) pFeature.Shape = pPolygon pFeature.Store() pAnnoElement = pFDOGraphicsRead.NextGraphic #Restore dataframe's previous extent pMap.ReferenceScale = ReferenceScale pMap.MapScale = MapScale pActiveView.Refresh if __name__ == '__main__': AnnotoPoly()
Thanks for converting this script. Any idea why the new polygons are being created in a different location than the original annotation layer?