Hi Igor,Hopefully someone will come up with a better answer than this but you can use ArcObjects in python so I converted the VBA script you mentioned to python. You will have to install the comtype modules for python and then load the ArcMap Modules. Luckily Mark Cederholm shows you how to do this see ArcMap and Python i.e.
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.
Then you're set for using ArcObjects in Python. Create a new script with the following in itOpen a new ArcMap session. Add an annotation layer and polygon layer and you're good to go.
# 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()