5

I wrote a Python function using comtypes to access ArcObjects to programmatically change the size of layer symbols in an MXD. The function works great in the Python window of ArcMap. However, I need to do this stand alone to do this for many MXD's.

Using arcpy I can open an MXD in memory like this:

mxd = arcpy.mapping.MapDocument(r'C:\some_folder\map.mxd)

I need to figure out how to do the above using ArcObjects (except return an instance of Application/IMxApplication). In my ArcObjects function, I am starting with a reference to the current open document. However, I cannot figure out how to do this without having a map document open.

I thought I could do something like this (using my own version of snippets):

import arcobjects
import comtypes.gen.esriFramework as esriFramework
import comtypes.gen.esriArcMap as esriArcMap
arcobjects.InitStandalone()
app = arcobjects.NewObj(esriArcMap.Application, esriFramework.IApplication) #this isn't doing the trick

And then calling app.OpenDocument() to point to the file path to actually open the MXD. This is not working and I do not know enough about initializing things in ArcObjects to know what I'm doing wrong. I know I cannot access anything from the AppROT to get a reference to the current running application because ArcMap/Catalog are not open.

In order to be able to call my function to set the symbol sizes, I need to pass in a reference to an IApplication instance (which I normally get this interface by using GetApp() or GetCurrentApp()). I cannot seem to find code samples for this anywhere. Does anyone know how to do this stand alone in Python?

Here is what I'm using to set the symbol sizes:

def setSymbolSize(pApp, layer_names=[], pointSize=12, lineWidth=1, autoSave=True):
 """sets the size/width of simple esri Marker or Line symbols
 Required:
 pApp -- open mxd instance, must be of type esriArcMapUI.IMxApplication
 Optional:
 layer_names -- list of layer names to set size of as they appear in TOC.
 pointSize -- size for all point layers specified. Default is 12
 lineWidth -- width for all line layers specified. Default is 1
 autoSave -- option to save document automatically after making changes.
 Default is True.
 """
 import comtypes.gen.esriDisplay as esriDisplay
 import comtypes.gen.esriArcMapUI as esriArcMapUI
 import comtypes.gen.esriCarto as esriCarto
 if isinstance(layer_names, (basestring)):
 layer_names = [layer_names]
 # defaults for point (shapeType 1) is 12, default for line (shapeType 3) is 2
 defaultSymbol = {1: esriDisplay.IMarkerSymbol,
 3: esriDisplay.ILineSymbol}
 # iterate through layer list
 for lyr in iterLayers(pApp):
 if lyr.Name in layer_names:
 # cast to esriCarto.IGeoFeatureLayer to get renderer
 flyr = CType(lyr, esriCarto.IFeatureLayer2)
 iGeo = CType(lyr, esriCarto.IGeoFeatureLayer)
 renderer = iGeo.Renderer
 # cast to simple renderer and then to simple symbol
 simple = CType(renderer, esriCarto.ISimpleRenderer).Symbol
 # cast to marker symbol interface and set size or width
 marker = CType(simple, defaultSymbol[flyr.ShapeType])
 if flyr.ShapeType == 1 and pointSize is not None:
 marker.Size = pointSize
 elif flyr.ShapeType == 3 and lineWidth is not None:
 marker.Width = lineWidth
 # refresh Map
 pDoc = pApp.Document
 pMxDoc = CType(pDoc, esriArcMapUI.IMxDocument)
 pMxDoc.UpdateContents()
 pMxDoc.ActiveView.Refresh()
 if autoSave in (True, 1):
 pApp.SaveDocument()
 return
asked Jan 18, 2016 at 21:23

1 Answer 1

6

Something like the following should work:

GetModule('esriCarto.olb')
import comtypes.gen.esriCarto as esriCarto
pMapDocument = CreateObject(esriCarto.MapDocument, esriCarto.IMapDocument)
pMapDocument.Open(path)
#Do stuff
pMapDocument.Save()
answered Jan 18, 2016 at 21:48
1
  • Thanks! That is way too easy, I was not aware of the MapDocument class from esriCarto. Commented Jan 18, 2016 at 22:12

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.