[GIS] How to create a polygon with an ArcGIS 10.1 python addin

arcgis-10.1arcgis-desktoparcmappython-addin

I'm looking for some code samples, or help with code to get me started. I've built a python addin menu which I would like to use to create polygon features in a specific layer in my edit session. enter image description here

So for example I would click 30×60 and a 30m x 60m rectangular polygon would be placed where I click.
I can't seem to find much on creating geometry within a python addin.
Thanks in advance for any comments or suggestions.
Frank

Best Answer

Note that currently, as far as I can tell, there is no way to get the current editable layer(s). See: How to get the editor's current layer in ArcPy?

So as an alternative you could have the user select a layer from the TOC and use the GetSelectedTOCLayerOrDataFrame method in the pythonaddins module to retrieve it.

If you can get over that, here is how you could implement the rest in a Python add-in:

  1. Implement a function that takes an x and y map coordinate, width and height dimensions for a rectangle, and a layer/feature class. The function then opens an InsertCursor on the layer, creates a new Polygon from the input coordinates and width and height, and inserts it using the cursor's insertRow method. Test this method outside of the add-in framework until you are sure it works as you expect.

    Below is a function I came up with that seems to work (it considers the x and y arguments to be the lower-left corner of the rectangle):

    def createRectangleAtPoint(x, y, width, height, layer):
        desc = arcpy.Describe(layer)
        bottom_left = (x, y)
        top_left = (x, y + height)
        top_right = (x + width, y + height)
        bottom_right = (x + width, y)
        array = arcpy.Array([arcpy.Point(*coords) for coords in [bottom_left, top_left, top_right, bottom_right, bottom_left]])
        rect = arcpy.Polygon(array, desc.spatialReference)
        with arcpy.da.InsertCursor(layer, "SHAPE@") as cursor:
           cursor.insertRow((rect,))
    
  2. In the implementation for your Tool class, listen for onMouseUpMap, retrieve the x and y coordinate arguments, and pass these in, along with the desired dimensions and layer, into the function above.

  3. Implement an Extension class that listens for onStartEditing, onStopEditing. Enable and disable your tool object when the edit session starts and stops.

    Note: Consider this step optional since this doesn't really prevent the user from running the code on a non-editable layer or one outside of the current edit session though, so there isn't that much point right now.