Get inner-most poly

Nice spatial relationship question today… a co-worker asked ‘how can i get only the inner-most poly from these clusters of polygons’. Looking at the data, none of the polygons overlap, these were clearly generated from contour lines.


There are likely a few ways to accomplish this, but our approach was as follows: recreate all polygons but fill in their inner holes, then count how many times each filled feature intersects an input feature… those that only intersect once are the inner-most.

The function we created returned the original dataset’s ObjectIDs

Code is as follows

import arcpy

#arcpy.env.overwriteOutput = True

def listOidOfPeaks(fc):
    oids = []

    # Eliminate ALL internal parts (basically fill in all the holes) , "in_memory\\EPP_tmp",
                        "AREA", "1000000 SquareKilometers", 0, "true")"in_memory\\EPP_tmp", "EPP_lyr")

    with arcpy.da.SearchCursor(fc, ("OID@", "SHAPE@",)) as c:
        # for each of the original poly feature's labelPoint (which
        #  is a point INSIDE the polygon) get the list of filled
        #  features being overlapped
        for row in c:
  "EPP_lyr", "INTERSECT",

            # put all the selected filled feature's ORIG_FID into a list
            oids += [i[0] for i in da.SearchCursor("EPP_lyr", ("ORIG_FID"))]

    # every OID which occurs only once are ones we want
    for i in sorted(oids):
        if oids.count(i) == 1:

# what's returned is a generator
oids = listOidOfPeaks("contour_polys.shp")

# bonus : turn a list of ids into a where_clause (I'm assuming FID is field name)
print("as a query :  FID in ({})".format(",".join(map(str, oids))))

The resulting where_clause which we can use with a number of GP tools such as Select Layer By Attribute

The New Python Window in ArcGIS Pro

ArcGIS Pro is coming with a totally redesigned UI, and the Python window is no exception.

First off: the Python window is meant to be a utility. It’s not most flashy of designs. You type in code and get feedback, it should help you do that and that is all. Our intention in the redesign wasn’t to get people super excited about typing code into a text box, it was to pleasantly surprise you with some helpful features and get out of your way.

The way it’s set up it a little different in Pro App. Here’s a quick tour of its design and features.

Split window

There are separate places for input and output


The biggest obvious change in the Python window is that it’s been divided into two pieces: the input section and the transcript section. We found from a usability point of view, mixing the input and output sections into one control could be confusing. You don’t have to skim the entire window to find where the newest prompt is, you just click in the bottom and start typing. It’s similar to a few other user interfaces we’ve used, old and new:


Help Tips

If you’re typing inside of a function call, you’ll get a list of parameters along with the current parameter highlighted:


We’re not blazing any new territory here, it’s just useful.


This is a carryover from every Python window ever, including the ArcGIS 10.X Python window. The Python window will try to guess what you’re looking for:


it works a little harder than most Python auto-completes and will let you even just type the first letter or two of something:


that’ll save a few keystrokes. And like the 10.X Python window, it gives extra help for geoprocessing tools:


Tools Show Up in History

Any GP tool you run in the Python window will show up in your current project’s Geoprocessing History. Outputs will be added to the current map.



When the Python interpreter is running, the Python input section is disabled and will show a “running” progressor. You can stop anything running in the Python window by hitting the “X” when it’s visible:


History Across Sessions

You can use [Ctrl-Up] and [Ctrl-Down] to go through previous commands you’ve issued in the Python window. It also saves them between sessions, so if you open up a new ArcGIS Pro instance, you can hit [Ctrl-Up] and get what you typed last time.

Drag And Drop

You can drag and drop pretty much anything into the Python window and it’ll try to guess what you want:


and Geoprocessing tools:


tools you’ve already run in the history show up as full Python snippets:


from Windows Explorer:


Comfortable And Productive

We can’t show this in screenshots, but a lot of the work we’ve put into the Python window is how it feels. Hopefully you’ll be more productive and the Python window will get out of the way and just let you do your job, speeding you up where it makes sense.

Split into equal length features

Request came in last week for a way to split a line feature into 10 equal length line features.

The input looked like this

The accepted solution came from Dave on the team who sent this elegant and efficient solution.

in_fc = r'c:\projects\waterway.gdb\stream'
out_fc = r'c:\projects\waterway.gdb\stream10'
out_count = 10 # how many features desired

line = arcpy.da.SearchCursor(in_fc, ("SHAPE@",)).next()[0]
arcpy.CopyFeatures_management([line.segmentAlongLine(i/float(out_count), ((i+1)/float(out_count)), True) for i in range(0, out_count)], out_fc)

Which outpus a new feature class containing 10 line features like so

How does it work? The first 3 lines are self explanatory. So we will skip.

The following line is also fairly simple, what it does is get the geometry (shape@) of the first record (we only ask for next() once). The [0] is needed to get just the first value in the record (remember cursors return lists of values).

polyline = arcpy.da.SearchCursor(in_fc, ("SHAPE@",)).next()[0]

Next is where the magic happens, python list comprehension is used to turn the polyline object into a list of 10 (as per the out_count variable) equal length segments generated by the segmentAlongLine function. This list of polyline is then used as input to CopyFeatures (as per Using geometry objects with geoprocessing tools) which writes out the 10 polyline as individual features into the output feature class (out_fc).

arcpy.CopyFeatures_management([polyline.segmentAlongLine(i/float(out_count), ((i+1)/float(out_count)), True) for i in range(0, out_count)], out_fc)

EDIT: As was pointed out in the comments, the segmentAlongLine is new at 10.3.


pretty print fields

This is a piece of code i’ve written and re-written dozens of times. Typically I code it on a whim for a single use.

Today I went the extra mile and made the output really nice, so here it is in case somebody has use for it.

And this is what you get as output in the python window*.

* this is the nice and new ArcGIS Pro’s python window.

The output is a bit too wide for use in terminal (80 characters) but within the app it’s nice and clear.

Happy coding.

Getting more arcpy help

A lot of people are posting requests asking for a particular snippet in the comments section of this blog.

By all means, continue to do so, we do enjoy tackling the more generic and broadly useful requests… but we just can’t tackle all of them, and not in a timely manner.

So if you need help with code, and you need it fairly soon, please consider also opening a discussion on the Esri geonet site.

Happy coding.

Python & arcpy presentations at the 2014 user conference

Once upon a time, there was but a single tech workshop at the Esri international user conference which featured everybody’s favorite scripting language. No longer is the Python offering so paltry. Behold, the 2014 user conference technical workshops & demo theaters returned when you search for “python”.

Consult the online agenda for date and time when these are offered.

Technical workshops

  • Python: Getting started
  • Python: Beyond the Basics
  • Python: Map Automation
  • Python Map Automation: An Introduction to arcpy.mapping
  • Python Map Automation: Beyond the Basics of arcpy.mapping
  • Python: Raster Analysis
  • Python: Building Geoprocessing Tools
  • Python for Analysis
  • Analyzing Multidimensional Scientific Data in ArcGIS
  • Automating Geodatabase Creation with Geoprocessing Tools
  • Creating Geoprocessing Services
  • Customizing ArcPad with JavaScript, Python, and VBScript
  • Desktop Mapping: Building Map Books
  • ArcGIS Online: Administering your ArcGIS Organization Through Scripting
  • ArcGIS for Server Administrative Scripting and Automation
  • ArcGIS Network Analyst: Automating Workflows with Geoprocessing
  • Integrating Open-Source Statistical Packages with ArcGIS
  • Useflul Python Libraries for The GIS Professional

Demo theater presentations

  • Administering ArcGIS for Server with Python
  • Building Live Data Feeds Using Python
  • Consuming Geoprocessing and Hosted Analytic Services in ArcGIS for Desktop
  • Debugging Python Scripts
  • Esri Production Mapping: Automating Map Production Workflows Using the ArcPyProduction Site Package
  • Geoprocessing on Image Services
  • Getting Started With Map Algebra Using the Raster Calculator and Python
  • Getting Started with Python in ArcGIS
  • Interacting with the ArcGIS Server Admin API using Python
  • Managing an Online Data Warehouse: Using Python to Publish Data to ArcGIS Online
  • Python Add-ins: Tips and Tricks