ArcMap and Python:
Closing the VBA Gap
Mark Cederholm
UniSource Energy Services
Esri Developer Summit 2012
Using ArcObjects in Python
Esri Developer Summit 2010
ArcMap and Python: Closing the VBA Gap
Tuesday 4:30 Mesquite C
Extend Python Using C++ and ArcObjects
Wednesday 11:15 Mesquite B
Download presentations and code:
[Link]
[Link]
[Link] PM
Why Python?
ArcGIS VBA support ends after 10.0
Python is integrated with ArcMap
Geoprocessing tasks: arcpy
ArcObjects manipulation: comtypes
Custom forms: wxPython
At 10.1, the ArcGIS add-in framework
supports Python
However, debugging can be difficult in
ArcMap
[Link] PM
The comtypes site package:
[Link]
The wxPython site package:
[Link]
[Link] PM
Modifying comtypes for 10.1:
Delete [Link], [Link],
[Link], [Link]
Edit [Link]
Add the following entry to the
_ctype_to_vartype dictionary (line 794):
POINTER(BSTR): VT_BYREF|VT_BSTR,
[Link] PM
Loading common ArcMap modules
At the Python prompt:
>>> from [Link] import GetModule
>>> GetModule("c:/program
files/arcgis/desktop10.1/com/[Link]")
[TIP: If loading one or modules fails, delete all files in the
comtypes/gen folder before trying again.]
See [Link] for examples of using comtypes
[Link] PM
Workaround: Array object
>>> import [Link] as
esriSystem
>>> from [Link] import CreateObject
>>> pArray = CreateObject("{8F2B6061-AB00-11D287F4-0000F8751720}",
interface=[Link])
[Link] PM
wxPython and ArcMap
Will not work out-of-the-box in the ArcMap
Python window
Use PySimpleApp in a dedicated extension
for the application MainLoop
Destroy does not work: use Show instead
The print command will not output to
the Python window from a form
[Link] PM
Customizing ArcMap, Method 1:
Creating a Framework component
(9.x and 10.0)
[Sample Code: ArcMap_Python\DemoCOM]
[Link] PM
Requires [Link]
Obtain by downloading and installing
Windows SDK 7.1:
[Link]
[Link] PM
Edit [Link] and [Link]
to set the correct ESRI paths:
[Link] PM
Open Windows SDK 7.1 Command
Prompt:
[Link] PM
Use [Link] to produce
[Link] and [Link]:
midl [Link]
midl [Link]
Use Python to register the COM objects*:
python [Link] -regserver
python [Link] -regserver
*WARNING: The file/module name is case sensitive!
[Link] PM
In ArcMap, add the
tool in Customize
Mode:
Activate the tool,
select a quote, and
draw a line:
[Link] PM
Use Python to unregister the COM objects:
python [Link] -unregserver
python [Link] -unregserver
[Link] PM
Customizing ArcMap, Method 2:
Creating an Add-in (10.1)
[Sample Code: ArcMap_Python\DemoAddin]
[Link] PM
Python Add-In Wizard see Obtaining
the Python Add-In Wizard in the ArcGIS
10.1 for Desktop Help:
[Link] PM
Select or create a working folder and set
other properties as desired:
[Link] PM
Add an extension (right-click on
EXTENSIONS):
[Link] PM
Add a toolbar:
Add a tool:
[Link] PM
Click Save, navigate to folder, and add
files from sample code:
Double-click [Link] to create addin:
[Link] PM
Double-click [Link] to
install add-in:
[Link] PM
In ArcMap, make sure extension is checked:
Toolbar automatically appears:
[Link] PM
TIP: Add script path to [Link] to enable
local imports
import os
import sys
sMyPath = [Link](__file__)
[Link](0, sMyPath)
[Link] PM
class DemoExtension(object):
_wxApp = None
def __init__(self):
[Link] = True
def startup(self):
try:
from wx import PySimpleApp
self._wxApp = PySimpleApp()
self._wxApp.MainLoop()
except:
sMsg = "Error starting extension:\n" + \
traceback.format_exc()
[Link](sMsg, "DemoAddIn")
[Link] PM
class DemoTool(object):
_pApp = None
_geometry = None
_sQuote = None
_dlg = None
def __init__(self):
[Link] = True
[Link] = 3
Not stubbed out
[Link] = "Line" # Can set to . . .
by default:
def onClick(self):
if self._dlg is None:
from QuoteDialog import QuoteDialog
self._dlg = QuoteDialog(sMyPath, self)
self._dlg.Show(True)
def deactivate(self):
if self._dlg is None:
return
self._dlg.Show(False)
def onLine(self, line_geometry):
self._geometry = line_geometry
[Link]()
[Link] PM
COM Interop: relative speed
0
10
20
30
40
50
60
70
80
90
100
C++
92
VBA
48
.NET
32
Python
24
IronPython
Java
16
Benchmark = 500+K ShapeCopy operations
[Link] PM
100
Some final tips:
When in doubt, check the wrapper code:
Python../Lib/site-packages/comtypes/gen
Avoid intensive use of fine-grained ArcObjects in
Python
For best performance, use C++ to create coarsegrained objects
Use geoprocessing objects and tools to simplify
supported tasks watch for performance, though
Read the desktop help to check out available
functionality in arcgisscripting (and arcpy at 10.x)
[Link] PM
Questions?
Mark Cederholm
mcederholm@[Link]
This presentation and sample code
may be downloaded at:
[Link]
For 9.x examples, see:
[Link]
[Link] PM