0

I've created a python toolbox (.pyt file) with 2 tools in it: Prep() creates various derived datasets; Track() does processing using the prepped data. The idea is for Prep to be run just once, interactively (from the user dialog), while Track will be run many times, interactively. Both tools are working perfectly when run interactively.

I would like, however, for Prep to call Track a single time after the prep work is done, with a default selection so that there is some processed output as well as the prepped data when it has completed -- this entails an internal call to Track() rather than an interactive call from its user dialog.

At the end of Prep's execute() method, I create an instance of Track, get its parameter info, assign parameter values, and invoke its execute() method with those parameters. The GPString and GPBoolean parameters work fine, but the GPFeatureLayer parameter does not: when I assign a Feature Layer object to the parameter value, nothing changes: the parameter value is still None after the assignment (in contrast, the other parameters show their assigned values after the assignments).

Here's how I'm assigning the parameter values and calling Track:

    track = Track()
    trackParams = track.getParameterInfo()
    trackParams[0].value = 'default'           # GPString
    # targetpoints_layer holds a point FeatureLayer returned from arcpy.mapping.ListLayers()
    trackParams[1].value = targetpoints_layer  # GPFeatureLayer
    # REPLACE_EXISTING holds a boolean value
    trackParams[2].value = REPLACE_EXISTING    # GPBoolean
    track.execute(trackParams, None)

Here's getParameterInfo() for the Track tool:

def getParameterInfo(self):
    params = []

    p = arcpy.Parameter(
        displayName='Track name',
        name='TrackName',
        datatype='GPString',
        parameterType='Required',
        direction='Input')
    params.append(p)

    p = arcpy.Parameter(
        displayName='Target point layer',
        name='TargetPointLayer',
        datatype='GPFeatureLayer',
        parameterType='Required',
        direction='Input')
    p.filter.list = ['Point']
    params.append(p)

    p = arcpy.Parameter(
        displayName='Replace existing outputs?',
        name='ReplaceExisting',
        datatype='GPBoolean',
        parameterType='Required',
        direction='Input')
    p.value = False
    params.append(p)

    return params

The first sign of trouble was when I attempted to get the name of the target point layer in Track.execute(): it threw an exception "AttributeError: 'NoneType' object has no attribute 'name'". I followed this back to what seems to be the problem: the assignment of the parameter value in Prep before the call to track.execute().

Inspecting trackParams[1].value before and after assigning it targetpoints_layer shows no change -- it's value is None both before and after. In contrast, inspecting the other parameter values before and after assignment shows them changing from None to 'longest' and False, respectively. Inspecting targetpoints_layer itself shows it is indeed a FeatureLayer object (for example, targetpoints_layer.isFeatureLayer is True). I can successfully assign targetpoints_layer to a new variable, but not to a parameter's value attribute.

Any ideas why the assignment is having no effect (nor throwing an exception)?

Do you see anything I'm doing wrong or failing to do?

Why do the other assignments work but not the feature layer one?

0

Two suggestions:

  1. arcpy.ImportToolbox(__file__)

    arcpy.my_toolbox_alias.Tracks(param1, param2, etc...)

  2. Pull all the processing code out of self.execute into its own method (or standalone function) so that all self.execute does is get values from parameters and call the real method/func with them. You can then call that method/func directly rather than mucking around trying to mock parameter objects.

  • Thanks! After posting this I kept digging and found your earlier answer on the same topic: link, and I applied it successfully. My curiosity remains about why my approach didn't (entirely) work: it seems completely reasonable -- and no more work than your approach -- to populate a list of Parameters when calling a method that expects a list of Parameters... and indeed it worked for some values. Why didn't it work for a FeatureLayer, and why is it (apparently) not the best way to go? (feel free to ignore... problem solved, which is the main thing). – GISmatters Jul 13 '18 at 13:10
  • @GISmatters I agree with you, it should work. I'm just so used to working around ArcGIS things that should work and don't that I've given up questioning why they don't. – user2856 Jul 13 '18 at 21:33

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.