2

I attended a pretty awesome demonstration from Jeffrey Barrette at the Esri UC a few weeks ago on creating dynamic tables in ArcMap. This functionality will greatly benefit the aviation department at my firm. I have got the scripting all taken care of for creating the dynamic tables in the Layout (using graphic and text elements). However, this works by cloning a horizontal line, vertical line, and two text elements.

I have already got a working function to add a text element to a map layout via comtypes and ArcObjects, but I cannot seem to get the graphic line part correct. I am using some of the basic functions from a modified version of Snippets (from https://bitbucket.org/maphew/canvec/src/eaf2678de06f/Canvec/Scripts/parco.py). Here is my function for adding a horizontal line:

def add_horizontal_line():
 GetDesktopModules()
 import comtypes.gen.esriFramework as esriFramework
 import comtypes.gen.esriArcMapUI as esriArcMapUI
 import comtypes.gen.esriSystem as esriSystem
 import comtypes.gen.esriGeometry as esriGeometry
 import comtypes.gen.esriCarto as esriCarto
 import comtypes.gen.esriDisplay as esriDisplay
 import comtypes.gen.stdole as stdole
 # set mxd
 pApp = GetApp() #current open mxd
 pDoc = pApp.Document
 pMxDoc = CType(pDoc, esriArcMapUI.IMxDocument)
 pMap = pMxDoc.FocusMap
 pAV = CType(pMap, esriCarto.IActiveView)
 pSD = pAV.ScreenDisplay
 # set coords for elment
 pFact = CType(pApp, esriFramework.IObjectFactory)
 pEnv = pAV.Extent
 x = (pEnv.XMin + pEnv.XMax) / 2
 y = (pEnv.YMin + pEnv.YMax) / 2
 # from point
 pUnk_pt1 = pFact.Create(CLSID(esriGeometry.Point))
 pPt = CType(pUnk_pt1, esriGeometry.IPoint)
 pPt.PutCoords(x, y)
 # to point
 pUnk_pt2 = pFact.Create(CLSID(esriGeometry.Point))
 pPt2 = CType(pUnk_pt2, esriGeometry.IPoint)
 pPt2.PutCoords(x + 500, y) # next point 500 units east to form straight line
 # line (from point - to point)
 pUnk_line = pFact.Create(CLSID(esriGeometry.Line))
 pLg = CType(pUnk_line, esriGeometry.ILine2)
 pLg.PutCoords(pPt, pPt2)
 # preset color according to RGB values
 pUnk_color = pFact.Create(CLSID(esriDisplay.RgbColor))
 pColor = CType(pUnk_color, esriDisplay.IRgbColor)
 pColor.Red, pColor.Green, pColor.Blue = (0,0,0) #black line
 # set line properties
 pUnk_line = pFact.Create(CLSID(esriDisplay.SimpleLineSymbol))
 pLineSymbol = CType(pUnk_line, esriDisplay.ISimpleLineSymbol)
 pLineSymbol.Color = pColor
 # create the actual element
 pUnk_elm = pFact.Create(CLSID(esriCarto.LineElement))
 pLineElement = CType(pUnk_elm, esriCarto.ILineElement)
 pLineElement.Symbol = pLineSymbol
 pElement = CType(pLineElement, esriCarto.IElement)
 pElement.Name = 'horizLine'
 pElement.Geometry = pLg
 # add to map
 pGC = CType(pMap, esriCarto.IGraphicsContainer)
 pGC.AddElement(pElement, 0)
 pGCSel = CType(pMap, esriCarto.IGraphicsContainerSelect)
 pGCSel.SelectElement(pElement)
 iOpt = esriCarto.esriViewGraphics + \
 esriCarto.esriViewGraphicSelection
 pAV.PartialRefresh(iOpt, None, None)
 return 

I am getting an Error (parameter is incorrect) in this line:

pElement.Geometry = pLg

However, from the API reference it says the ILine2 interface PutCoords method can be used to set coordinates of the line using a FromPoint and ToPoint (IPoint objects). My understanding of ArcOjbects is not very strong, but it seemed from help docs that this would work. I even tried to explicitly set the pLg.FromPoint and ToPoint passing in the appropriate coordinates and that did not work either. Does anyone know what I'm doing wrong here?

asked Jul 30, 2014 at 14:56

1 Answer 1

4

Try replacing this line:

pUnk_line = pFact.Create(CLSID(esriGeometry.Line))

with this:

pUnk_line = pFact.Create(CLSID(esriGeometry.Polyline))

In the help on LineElementClass is says right at the bottom:

Geometry: LineElement accepts geometry of type esriGeometryPolyline. The Polyline is used as the geometry with which the symbol is drawn.

answered Jul 30, 2014 at 15:08
8
  • Thanks (Duncan?). That sounded promising, but unfortunately it did not work. Now it does not seem to create an ILine2 interface instance. My pLg variable is returned as a NoneType which not to my surprise I get the error "NoneType" object has no attribute PutCoords. Commented Jul 30, 2014 at 15:16
  • 1
    Well I've never actually attempted to use ArcObjects via Python but I do use it in VB. Don't worry the code looks OK to me it's some quirk that needs ironing out. Commented Jul 30, 2014 at 15:24
  • 1
    I would add it's always nice to see some comments in the code, can't get enough of that especially in ArcObjects! :) Commented Jul 30, 2014 at 15:27
  • 1
    And if I could bug you one more time, for some reason the pElement.Name property is not being set. I just looked back in the help docs and I see why...That is because apparently I made that up because it has no "Name" property. Any ideas on how to name an element? Or just what interface I'd do that in? I could probably figure it out from there. Once I have the element named, I can get at it with arcpy mapping. Edit - Nevermind, got it! Found the IElementProperties interface! I'm loving the power of ArcObjects...Now I just need to learn C# or VB :) Commented Jul 30, 2014 at 15:44
  • 1
    I think you only ever crack ArcObjects when you fully accept that navigating the help file is the first thing you must do. It's usually all in there. But there are many parts of the help file that simply don't give you enough information or examples and then you end up at websites like these. Commented Jul 30, 2014 at 15:57

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.