python/arcpy code from the 2014 dev summit

Hey Everyone,

it was great meeting and talking to everybody at the dev summit.

A number of python/arcpy presenters already shared their code to github repos below.

Happy coding.

merge polyline paths

Somebody on the team was having trouble tracing streams due to breaks in the streams introduced when converting raster to feature.

So here is slick little solution which takes n paths in a line features and makes a 1 path (aka 1 part) out of it.
None of the vertices are moved. Where there were two paths separated by a gap you will have one path with no gap.

To work property the paths have to be pointed in the same direction and not be converging. To deal with that would require quite a bit more logic.

As is script modified data in place, so back up your data before using.

Using os.startfile and webbrowser.open in ArcGIS for Desktop

os.startfile and webbrowser.open are two very useful functions in the Python library. However, due to some conflicts in the way the Windows libraries expect to be called, they can fail or crash when called within ArcGIS for Desktop in an add-in script or geoprocessing script tool (see the Remarks section on this MSDN reference page).

import functools
import os
import threading
import webbrowser

# A decorator that will run its wrapped function in a new thread
def run_in_other_thread(function):
    # functool.wraps will copy over the docstring and some other metadata
    # from the original function
    @functools.wraps(function)
    def fn_(*args, **kwargs):
        thread = threading.Thread(target=function, args=args, kwargs=kwargs)
        thread.start()
        thread.join()
    return fn_

# Our new wrapped versions of os.startfile and webbrowser.open
startfile = run_in_other_thread(os.startfile)
openbrowser = run_in_other_thread(webbrowser.open)

The local functions startfile and openbrowser will be made available, which have the same parameters as the versions in the standard library but will run in another thread and therefore work as expected.

Get coded-value descriptions when accessing data with cursors

This question was recently asked on twitter:

@arcpy Can you point me to an example python script where a SearchCursor returns coded-value descriptions instead of the codes?”

With ArcGIS 10.1, the data access module contains functions for listing subtypes and listing domains. Here are recipes to get descriptions rather than just the codes either for subtypes or domains:

1. Get subtype descriptions

fc = r'c:\data\Portland.gdb\roads'
# Create a dictionary of subtype codes and descriptions.
desc_lu = {key: value['Name'] for (key, value) in arcpy.da.ListSubtypes(fc).iteritems()}
with arcpy.da.SearchCursor(fc, "SUBTYPEFIELD") as cur:
    for row in cur:
        print(desc_lu[row[0]])

2. Get domain descriptions

gdb = r'c:\data\Portland.gdb'
# Get the dictionary of codes and descriptions for the Floodplain_Rules domain.
desc_lu = [d.codedValues for d in arcpy.da.ListDomains(gdb) if d.name == 'Floodplain_Rules'][0]
with arcpy.da.SearchCursor(os.path.join(gdb, "floodplain"), 'RuleID') as cur:
    for row in cur:
        print(desc_lu[row[0]])

* NOTE: If you are running ArcGIS 10.1 with no service packs, just do the following to get a dictionary of subtype codes and descriptions. ListSubtypes was enhanced at ArcGIS 10.1 SP1.

desc_lu = arcpy.da.ListSubtypes(fc)

Listing Database Views

When using ListTables() or ListFeatureClasses() with an enterprise geodatabase, the returned list will include the database views. In many cases, users name views with a unique prefix or suffix for distinction (i.e. VW_PARCELOWNERS or PARCELOWNERS_VW). For views with such a naming convention, you can get a list of them by using a list comprehension:

arcpy.env.workspace = r"c:\data\CityOfRedlands.sde"
views = [v for v in arcpy.ListTables() if v.endswith("_VW")]

If views have no specific naming convention or you want to ensure all the views are returned, you can use the ArcSDESQLExecute class.

For SQL Server:

sql_execute = arcpy.ArcSDESQLExecute(r'Database Connections\SQLSERVERDB.sde')
views = sql_execute.execute("select name from sys.objects where type = 'V'")

For Oracle:

sql_execute = arcpy.ArcSDESQLExecute(r'Database Connections\MYORACLEDB.sde')
# List user views
views = sql_execute.execute("select view_name from user_views")

For other database types, be sure to provide the correct SQL expression.