ArcPy - mikedorais/python_learning GitHub Wiki

ArcPy Notes

ArcGIS Pro ArcPy Reference

Running Python From a command prompt

To start Python from a command prompt, type the following:

"%PROGRAMFILES%\ArcGIS\Pro\bin\Python\Scripts\propy"

Note:

All paths shown assume a per machine (all users) installation of ArcGIS Pro. If ArcGIS Pro has been installed for the current user, substitute %LOCALAPPDATA% for %PROGRAMFILES%.

To run a Python script from a command prompt (arguments can be added following the .py file), type the following:

"C:\Program Files\ArcGIS\Pro\bin\Python\Scripts\propy" myscript.py

Start the ArcGIS Pro Python 3 conda environment:

"%PROGRAMFILES%\ArcGIS\Pro\bin\Python\Scripts\proenv"

Since I have put proenvin my path if I want to run from Visual Studio Code all I do is type:

> proenv
> code .

Then it works fine to do the repl. TBD: If I can debug in code.

arcpy submodules

Find out the submodules in arcpy by:

import types
for key, obj in arcpy.__dict__.items():
    if type(obj) is types.ModuleType:
        print(key)

management
edit
pdfdocument
md
arcobjectconversion
analysis
_chart
_management
_renderer
utils
wmx
arcpy
geometries
imp
warnings
sys
da
sfa
cartography
winreg
conversion
os
mp
lr
_na
stpm
glob
geocoding
_wmx
_mp
locref
_symbology
arcobjects
_base
server
ga
_graph
sa
reviewer
geoprocessing
time
numpy
ddd
toolbox
ra
stats
na
mixins
geoanalytics
_ga

Data Access Module

arcpy.da

SearchCursor

SearchCursor(in_table, field_names, {where_clause}, {spatial_reference}, {explode_to_points}, {sql_clause})

Considerations When Using SearchCursor (and other cursors)

Note: SearchCursor on a TableView run form the ArcGIS Pro GUI will only include the selected rows. There does not appear to be a way to force it to get all rows whether they are selected or not and preserve the selection unless the selection is saved, cleared, and restored.
At least to clear the selection this can be

arcpy.SelectLayerByAttribute_management(record_set, "CLEAR_SELECTION")

But there is a a gotcha. If record_set was defined as a Record Set parameter to a script tool and retrieved using arcpy.GetParameter(), it will still be a TableView, not a RecordSet. That is also a problem if it is retrieved as a table from Map.listTables(). To be sure it is a RecordSet just convert it to one using arcpy.RecordSet(record_set). When converted this way, all records, even unselected ones are part of the RecordSet. This prevents the need to clear the selection first to get all records. There may be some overhead to this though, so it probably shouldn't be done for large tables. Also, I only know it to work when the TableView comes in through arcpy.GetParameter() with type of RecordSet. Note: It doesn't come in as a RecordSet type though. That technique doesn't work from the command line. All of the equivalent of the above applies to features with Map.listLayers, Layer and FeatureSet.

It may not be clear in any given case (depending on whether it is a feature class, table view, or record set, and whether it participates in joins) what the field names are that should be used. The field names can be determined on the same object used for the in_table parameter of SearchCursor by running the following code. However it does not appear to work, at least not consistently, for all RecordSet objects (may have to do with whether they were derived from a table view with a join?). But for a RecordSet you can access the .JSON property and get it as JSON string and examine the schema in that to determine field names and types.

for field in arcpy.ListFields("{table view name}"):
    print(field.name)
with arcpy.da.SearchCursor(in_table=layerTableOrView, field_names=['SHAPE@', 'fieldName']) as cursor:
    for row in cursor:
        field1 = row[0]

Note that field names are often in the form tablename.fieldname, especially for RecordSet and table view with joined fields.

Special fields:

  • SHAPE@XY —A tuple of the feature's centroid x,y coordinates.
  • SHAPE@TRUECENTROID —A tuple of the feature's true centroid x,y coordinates.
  • SHAPE@X —A double of the feature's x-coordinate.
  • SHAPE@Y —A double of the feature's y-coordinate.
  • SHAPE@Z —A double of the feature's z-coordinate.
  • SHAPE@M —A double of the feature's m-value.
  • SHAPE@JSON — The esri JSON string representing the geometry.
  • SHAPE@WKB —The well-known binary (WKB) representation for OGC geometry. It provides a portable representation of a geometry value as a contiguous stream of bytes.
  • SHAPE@WKT —The well-known text (WKT) representation for OGC geometry. It provides a portable representation of a geometry value as a text string.
  • SHAPE@ —A geometry object for the feature.
  • SHAPE@AREA —A double of the feature's area.
  • SHAPE@LENGTH —A double of the feature's length.
  • OID@ —The value of the ObjectID field.
>>> fieldnames = ['OID@', 'Name', 'SHAPE@', 'SHAPE@XY', 'SHAPE@X', 'SHAPE@Y', 'SHAPE@JSON', 'SHAPE@WKT']
>>> facility_list = list()
>>> with arcpy.da.SearchCursor('Closest Facility/Facilities', fieldnames) as cursor:
...    for row in cursor:
...        facility_dict = dict()
...        for fieldIndex in range(0, len(fieldnames)):
...            facility_dict[fieldnames[fieldIndex]] = row[fieldIndex]
...        facility_list.append(facility_dict)
>>> facility_list
[{'SHAPE@WKT': 'POINT (1915187.1559000015 561219.18890000135)',
  'Name': 'Test4',
  'SHAPE@': <PointGeometry object at 0x1cd4f148400[0x1cd4e7f8eb8]>,
  'OID@': 4,
  'SHAPE@JSON': '{"x":1915187.1559000015,"y":561219.18890000135,"spatialReference":{"wkid":26946,"latestWkid":26946}}',
  'SHAPE@X': 1915187.1559000015, 
  'SHAPE@Y': 561219.1889000013, 
  'SHAPE@XY': (1915187.1559000015, 561219.1889000013)}]

Mapping Module

Classes

ArcGISProject

# From Python Window only:
aprx = arcpy.mp.ArcGISProject("CURRENT")
for m in aprx.listMaps():
    print("Map: " + m.name)
    for lyr in m.listLayers():
        print("  " + lyr.name)
print "Layouts:"
for lyt in aprx.listLayouts():
    print("  {0} ({1} x {2} {3})".format(lyt.name, lyt.pageHeight, lyt.pageWidth, lyt.pageUnits))

Map

import arcpy
aprx = arcpy.mp.ArcGISProject(r"C:\Projects\YosemiteNP\Yosemite.aprx")
insertLyr = arcpy.mp.LayerFile(r"C:\Projects\YosemiteNP\LayerFiles\Ranger Stations.lyrx")
m = aprx.listMaps("Yosemite National Park")[0]
refLyr = m.listLayers("Points of Interest")[0]
m.insertLayer(refLyr, insertLyr, "BEFORE")
aprx.saveACopy(r"C:\Projects\YosemiteNP\Yosemite_updated.aprx")

Network Analyst Module

Saving some notes I had put in comments in code before that test/learning file gets deleted:

import subprocess
import arcpy

def main():
    closet_facility_layer = arcpy.GetParameterAsText(0)
    # feature_dataset_output = arcpy.GetParameterAsText(1)

    # closet_facility_layer is the name of the closest facility network analysis layer
    # get its description to get access to its properties
    # https://pro.arcgis.com/en/pro-app/arcpy/functions/network-analyst-layer-properties.htm
    closest_facility_layer_desc = arcpy.Describe(closet_facility_layer)

    if closest_facility_layer_desc.dataType != 'NALayer':
        print("Error") #TODO: better error message reporting
        arcpy.SetParameter(1, "closest_facility_layer_desc.dataType != 'NALayer'")
        return

    if closest_facility_layer_desc.solverName != 'Closest Facility Solver':
        print("Error") #TODO: better error message reporting
        arcpy.SetParameter(1, "closest_facility_layer_desc.solverName != 'Closest Facility Solver'")
        return

    # Every Describe object may have any of these properties, if relevant (https://pro.arcgis.com/en/pro-app/arcpy/functions/describe-object-properties.htm)
    # name, baseName, catalogPath, path, file, extension, dataElementType, dataType, children (Describe Object), childrenExpanded (Boolean), fullPropsRetrieved (Boolean), metadataRetrieved (Boolean), 
    # dataType String (Read Only): The type of the element (what this returns is described in the documentation for each type of described object)
    

    # These properties are available for a closest facility layer describe object
    # The properties common to all the network analyst solvers such as impedance can be determined by directly describing the network analysis layer and are listed here:
    #
    # impedance String (Read Only): The network cost attribute used as the impedance during the analysis.
    # accumulators String (Read Only): A semicolon-separated list of network cost attributes that are accumulated as part of the analysis.
    # restrictions String (Read Only): A semicolon-separated list of restriction attributes that are applied for the analysis.
    # ignoreInvalidLocations Boolean (Read Only): Indicates the way in which the solver considers invalid network locations within the Network Analyst classes.
    #                                    A value of True indicates that the invalid locations are ignored by the solver. False indicates that the invalid locations are not ignored by the solver.
    # uTurns String (Read Only): Indicates how the U-turns at junctions, which could occur during network traversal between stops, are being handled by the solver:
    #                    ALLOW_UTURNS
    #                    NO_UTURNS
    #                    ALLOW_DEAD_ENDS_ONLY
    #                    ALLOW_DEAD_ENDS_AND_INTERSECTIONS_ONLY
    # useHierarchy String (Read Only): Indicates if the Network Analyst Layer is using Hierarchy: USE_HIERARCHY, NO_HIERARCHY
    # hierarchyAttribute String (Read Only): The name of the hierarchy attribute.
    # hierarchyLevelCount Integer (Read Only): The number of hierarchy ranges used to define the hierarchy attribute. The maximum value is 3.
    # maxValueForHierarchyX Integer (Read Only): A given hierarchy attribute can have values that define the hierarchy ranges. The maximum values for each range can be obtained from maxValueForHierarchyX property, where X indicates the hierarchy level.
    # locatorCount Integer (Read Only): The total number of classes that are used to search through for determining a network location. 
    # locators Network Analyst Locator object (Read Only): This object can be used to obtain name, snap type, and the search query information for the classes that are used for finding network locations.
    # findClosest String (Read Only): Indicates how the network source features are searched when locating network analysis objects: MATCH_TO_CLOSEST, PRIORITY
    # searchTolerance String (Read Only): A space-separated string indicating the search tolerance and the units used when finding the network locations.
    # excludeRestrictedElements String (Read Only): Indicates if the network analysis objects can be located only on traversable portions of network sources: INCLUDE, EXCLUDE
    # children List (Read Only): Returns a Python List of describe objects that reference individual network analysis classes (such as stops and routes) as layers.  ( cannot be used with the network analysis layer stored on disk as a layer file.)
    # parameterCount Integer (Read Only): The total number of attribute parameters defined for all the network attributes of the underlying network dataset used by the Network Analyst layer.
    
    # For properties specific to a particular solver, they need to be obtained via the solverPoperties object

    # solverProperties Network Analyst Solver object (Read Only) This object can be used to determine the solver-specific properties in a Network Analyst layer.
    # May be one of the following Describe objects: Route Solver Properties, Service Area Solver Properties, Closest Facility Solver Properties, OD Cost Matrix Solver Properties, Locataion Allocation Solver Properties
    # in our case solverProperties should be returning a Closest Facility Solver Properties Describe object.
    cfSolverProps = closest_facility_layer_desc.solverProperties

    # Closest Facility Solver Properties Describe object has these properties:
    # cfRoutesShape String (Read Only): The shape type for the route features that are output by the solver:
    #                                   TRUE_LINES_WITHOUT_MEASURES
    #                                   TRUE_LINES_WITH_MEASURES
    #                                   NO_LINES
    #                                   STRAIGHT_LINES
    # defaultCutoff Double (Read Only): The default impedance value at which to stop searching for facilities for a given incident. If no cutoff value is specified in the network analysis layer, the property returns an empty string.
    # defaultTargetFacilityCount Integer (Read Only): The default number of closest facilities to find per incident.
    # timeOfDay String String (Read Only): Indicates the time and date at which the routes begin or end. The interpretation of this value depends on whether timeOfDayUsage property is set to START_TIME or END_TIME.
    # timeOfDayUsage String (Read Only): Indicates whether the value of the timeOfDay property represents the arrival or departure times for the routes: START_TIME, END_TIME, NOT_USED
    # timeZoneUsage String (Read Only): The direction of travel between facilities and incidents: TRAVEL_TO, TRAVEL_FROM
    # travelDirection String (Read Only): The direction of travel between facilities and incidents: TRAVEL_TO, TRAVEL_FROM

    # parameters Network Attribute Parameter object (Read Only): This object can be used to determine the attribute parameters used for the network analysis.
    cfNetworkAttributeParams = closest_facility_layer_desc.parameters

    # network property Network Dataset object (Read Only): This object can be used to get all the properties, such as catalogPath, of the underlying network dataset used by the analysis layer.
    # https://pro.arcgis.com/en/pro-app/arcpy/functions/network-dataset-properties.htm
    cfNetworkDS = closest_facility_layer_desc.network

    # catalogPath String (Read Only): The path of the network dataset.
    networkDSCatalogPath = cfNetworkDS.catalogPath