Select to view content in your preferred language

"Hey did you know this?" Tool Results on steroids...

3970
6
08-31-2016 07:18 AM
Labels (1)
DanPatterson_Retired
MVP Emeritus
3 6 3,970

This blog is inspired by this thread https://community.esri.com/docs/DOC-2436#comment-9031 by Steve Offermann (Esri).  He suggested a very simple way to extend the capabilities of tool results and how to parse arguments for them.  I recommended the use of the Results window outputs in a previous blog.  Hats off to Steve.

I am only going to scratch the surface by presenting a fairly simple script...which could easily be turned into a tool.

In this example, a simple shapefile of hexagons, (presented in another blog post) was processed to yield:

  • an extent file, giving the bounds of each of the input hexagons,
  • the hexagon corners as points and sent to a shapefile, and,
  • the centroids of each hexagon was treated in a similar fashion

The whole trick is to parse your processes down into parameters that can be shared amongst tools.  In this case, tools that can be categorized as:

  • one parameter tools like:  AddXY_management and CopyFeatures_management
  • two parameter tools like:
    • FeatureEnvelopeToPolygon_management,
    • FeatureToPoint_management and
    • FeatureVerticesToPoints_management

This can then be amended by, or supplemented with, information on the input/output shape geometries.  I demonstrate this by calculating the X,Y coordinates for the point files.

So you are saying ... I don't do that stuff ... well remember, I don't do that webby stuff either.   Everyone has a different workflow and if my students are reading this, just think how you could batch project a bunch of files whilst simultaneously renaming them etc etc.  The imagination is only limited by its owner...

First the output....

Hexagon_outputs.png

And now the script....

"""
Script:   run_tools_demo.py
Author:   Dan.Patterson@carleton.ca

Source:   Stefan Offermann
Thread:   https://community.esri.com/docs/DOC-2436

Purpose:  Results window on steroids
  - take a polygon shapefile, determine its envelop,
  - convert the feature to centroids,
  - convert to feature points
  - calculate X,Y for all of the above
  - then make a back of everything
Requires:
  - a source file
  - an output folder
  - a list of tools to run
"""
import os
import arcpy 
arcpy.env.overwriteOutput = True
in_FC = "c:/!BlogPosts/Runtools_Demo/Shapefiles/pointy_hex.shp"
path,in_File = os.path.split(in_FC)
path += "/"
backup = "c:/temp/shapefiles/"    # some output folder
# file endings
end = ["_env","_fp","_vert"]      # envelop, feature to point, feature vertices
# two argument tools
two_arg = ["FeatureEnvelopeToPolygon_management",
           "FeatureToPoint_management",
           "FeatureVerticesToPoints_management"
          ]
# one argument tools
one_arg =["AddXY_management", "CopyFeatures_management"]
#
outputs = [in_FC.replace(".shp", end+".shp") for i in range(len(end))]
backups =  [outputs.replace(path, backup) for i in range(len(end))]
#
polygons = []
points = []
for i in range(len(two_arg)):                  # run the two argument tools
    args = [in_FC, outputs]                 # select the output file
    result = getattr(arcpy, two_arg)(*args) # run the tool...and pray
    frmt = '\Processing tool: {}\n  Input: {}\n  Output: {}'
    print(frmt.format(tools, args[0], args[1]))
#
for i in range(len(outputs)):
    args = [outputs]
    print(outputs, arcpy.Describe(outputs).shapeType)
    if arcpy.Describe(outputs).shapeType == 'Point':
        result = getattr(arcpy, one_arg[0])(*args) # calculate XY
    result_bak = getattr(arcpy, one_arg[1])(result, backups) # backup
    print('Calculate XY for: {}'.format(result))
    print('Create Backups: {}\n  Output: {}'.format(result,result_bak))
‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍
‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍

Enjoy and experiment with your workflows.

6 Comments
XanderBakker
Esri Esteemed Contributor

When I saw the thread by Stefan Offermann‌, I did't know how this could actually be translated into something "useful". Glad you came up with a use case. Kudos +1.

DarrenWiens2
MVP Alum

Hi Dan,

Thanks for this example. Just to be the devil's advocate, I'll add that I'm still not exactly sold on the practicality of using it.

As far as I can tell, you save yourself two lines in the two_arg loop (over making 3 individual calls), and nothing at all in the one-arg loop.

result = getattr(arcpy, one_arg[0])(*args) can be rewritten as: result = arcpy.AddXY_management(outputs)

and...

result_bak = getattr(arcpy, one_arg[1])(result,backups) can be rewritten: result_bak = arcpy.CopyFeatures_management(outputs,backups)

Unless you're looping through tools, there is no benefit I can see and it reduces readability (for me, at least). I do admit that this is a slick way to loop through tools, however, you need a special script that requires multiple tools with the exact same combination of parameters in order to take advantage of it. I'd be interested to see a spreadsheet listing tools vs parameter type to see which tools would be compatible with each other.

DanPatterson_Retired
MVP Emeritus

Darren
As I said, a simple example, that script can serve as a shell...

I am working on such as list as you suggest based upon the workflows I do (data conversion etc and things related to computation geometry and statistics). 
For a student (or others), it could be a great substitute for modelbuilder.  People often get unexpected results when they fail to define model parameters, get things out of order, don't understand iterations etc etc.  In short, they get caught up on all the cool colors and shapes.  A tool in a toolbox, on the other hand, linearizes this and is more useful for people that think that way  (ie batch projection, with batch field additions and calculations based upon geometry type and associated with summary statistics... a pain and one that have we all have scripts for).

This also opens up some interesting aspects when working with numpy arrays that I hadn't fully understood on StackOverflow (I will report).  I would also like to see script to modelbuilder functionality rather than the otherway around

TedKowal
Honored Contributor
# run the tool...and pray      --- How true  Love it!
DuncanHornby
MVP Notable Contributor

A very interesting blog but I agree with dkwiens‌ I find this approach less easy to read and follow. For longevity of code, readability in my mind is as important as funkiness and this technique sure is funky! I'm glad you have written this blog as it shows a technique I have never used and if I ever come across it I'll have a chance at least understanding it but ultimately it is down to personal coding preference styles.

DanPatterson_Retired
MVP Emeritus

expansion and use of variable arguments has come in very handy in a slightly different incarnation, one that I employ all the time while printing and I don't know the number of inputs that are required.... for example...

>>> a = [4, "args", [1,2,3], "expanded"]
>>> frmt = ("{} "*len(a))
>>> print(frmt.format(*a))
4 args [1, 2, 3] expanded 
About the Author
Retired Geomatics Instructor at Carleton University. I am a forum MVP and Moderator. Current interests focus on python-based integration in GIS. See... Py... blog, my GeoNet blog...
Labels