Recursive list feature classes

UPDATE: At 10.1 service pack 1, this can be more easily achieved using arcpy.da.Walk. Also see Inventorying data.

The following function (recursive_list_fcs) will return a list of all feature classes that fall under the input workspace, including those not seen by the file system such as in a file geodatabase.

import os
import arcpy


def recursive_list_fcs(workspace, wild_card=None, feature_type=None):
    """Returns a list of all feature classes in a tree.  Returned
    list can be limited by a wildcard, and feature type.
    """
    preexisting_wks = arcpy.env.workspace
    arcpy.env.workspace = workspace

    try:
        list_fcs = []
        for root, dirs, files in os.walk(workspace):
            arcpy.env.workspace = root
            fcs = arcpy.ListFeatureClasses(wild_card, feature_type)
            if fcs:
                list_fcs += [os.path.join(root, fc) for fc in fcs]

            # Pick up workspace types that don't have a folder
            #  structure (coverages, file geodatabase do)
            workspaces = set(arcpy.ListWorkspaces()) - \
                         set(arcpy.ListWorkspaces('', 'FILEGDB')) -\
                         set(arcpy.ListWorkspaces('', 'COVERAGE'))

            for workspace in workspaces:
                arcpy.env.workspace = os.path.join(root, workspace)
                fcs = arcpy.ListFeatureClasses(wild_card,
                                               feature_type)

                if fcs:
                    list_fcs += [os.path.join(root, workspace, fc)
                                 for fc in fcs]

            for dataset in arcpy.ListDatasets('', 'FEATURE'):
                ds_fcs = arcpy.ListFeatureClasses(wild_card,
                                                  feature_type,
                                                  dataset)
                if ds_fcs:
                    list_fcs += [os.path.join(
                        root, workspace, dataset, fc)
                                 for fc in ds_fcs]

    except Exception as err:
        raise err
    finally:
        arcpy.env.workspace = preexisting_wks

    return list_fcs
Advertisements

Listing Attribute Domains

The data access (arcpy.da) module in ArcGIS 10.1 delivers a function for listing attribute domains, whereby, you can retrieve all the properties for each domain. Here is an example of listing and describing all the attribute domains for a geodatabase:

import arcpy

domains = arcpy.da.ListDomains("C:/Boston/Boston.gdb")
for domain in domains:
    print('Domain name: {0}'.format(domain.name))
    if domain.domainType == 'CodedValue':
        coded_values = domain.codedValues
        for val, desc in coded_values.iteritems():
            print('{0} : {1}'.format(val, desc))
    elif domain.domainType == 'Range':
        print('Min: {0}'.format(domain.range[0]))
        print('Max: {0}'.format(domain.range[1]))

To copy domains from one geodatabase to another, copy the function from the following location:
https://gist.github.com/1877237

Create a list of unique field values

This function can be used to return a unique list of field values. It takes advantage of the new data access module in ArcGIS 10.1.

def unique_values(table, field):
    with arcpy.da.SearchCursor(table, [field]) as cursor:
        return sorted({row[0] for row in cursor})

Here is an example of the return values:

>>> unique_values(r’C:\boston\city.gdb\crime’, ‘DAY’)
[u’Mon’, u’Sun’, u’Tues’, u’Wed’]

Calculate a unique value for each record

In this example, a unique value is calculated for each record starting with 1. The result is 1, 2, 3 … to the number of records. This is often necessary when you have to do some spatial operation and perform a join or relate using that field. It can also be useful when your table doesn’t have an OBJECTID field.

This code uses the data access module available with ArcGIS 10.1.

import arcpy
with arcpy.da.UpdateCursor(r"C:\Data\city.gdb\crime", "UID") as rows:
    for i, row in enumerate(rows, 1):
        row[0] = i
        rows.updateRow(row)

Find overlapping features

In ArcGIS 10, additional functions for performing relational operations was added to the geometry object. The following code uses the overlaps function to find overlapping features and prints out the ObjectID pairs. For a complete list of relational operators, see the Geometry class.

This code is supported in ArcGIS 10.0.

def find_overlaps(input_features):
    '''Find and print OID value pairs for overlapping features.'''
    oid_field = arcpy.ListFields(input_features, '*', 'OID')[0]
    for row in arcpy.SearchCursor(input_features, '', '', 'Shape;{0}'.format(oid_field.name)):
        for row2 in arcpy.SearchCursor(input_features, '', '', 'Shape;{0}'.format(oid_field.name)):
            if row2.Shape.overlaps(row.Shape):
                print '{0} overlaps {1}'.format(str(row2.getValue(oid_field.name)), str(row.getValue(oid_field.name)))

ArcGIS 10.1 introduces a new data access module, arcpy.da, for working with data. It includes cursor functions which provide improved cursor support and faster performance. The following code can replace the previous sample code and provide improved performance.

From more information about arcpy.da, see the data access module.

def find_overlaps(input_features):                
    '''Find and print OID value pairs for overlapping features.'''
    for row in arcpy.da.SearchCursor(input_features, ('OID@', 'SHAPE@')):
        for row2 in arcpy.da.SearchCursor(input_features, ('OID@', 'SHAPE@')):
            if row2[1].overlaps(row[1]):
                print '{0} overlaps {1}'.format(str(row2[0]), str(row[0]))

Calculate a mean value from a field

Here’s a function to return a mean value from a field by taking advantage of the Summary Statistics tool.

This code is supported in ArcGIS 10.0:

def calculate_mean_value(table, field):
    stats_table = r"in_memory\stats"
    arcpy.Statistics_analysis(table, stats_table, [[field, "MEAN"]])
    mean_field = "MEAN_{0}".format(field)
    cursor = arcpy.SearchCursor(stats_table, "", "", mean_field)
    row = cursor.next()
    mean_value = row.getValue(mean_field)
    del cursor
    return mean_value

 

ArcGIS 10.1 introduces a new data access module, arcpy.da, for working with data. It includes functions for converting tables and feature classes to and from NumPy arrays, as well as, cursor functions which provide improved cursor support and faster performance. The following code can replace the previous sample code when using ArcGIS 10.1.

From more information about arcpy.da, see the data access module.

def calculate_mean_value(table, field):
    na = arcpy.da.TableToNumPyArray(table, field)
    return numpy.mean(na[field])