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

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()
1
  • Thanks! That is way too easy, I was not aware of the MapDocument class from esriCarto. Commented Jan 18, 2016 at 22:12

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.