4

I want to specify an input for each column of the 'field compare' parameter, so it would be 'baseFeatures' would link just to the 'Base Fields' column and 'updatedFeatures' would just link to the 'Updated Fields' column. This is basically what 'Compare Fields' do in the 'Detect Feature Changes' tool.

This is what I did.

class Tool(object):
def __init__(self):
 """Define the tool (tool name is the name of the class)."""
 self.label = "Compare Features"
 self.description = "Compare the features from two datasets (a base one and an updated one)" + \
 "and returns the desired outputs."
 self.canRunInBackground = False
def getParameterInfo(self):
 """Define parameter definitions"""
 baseFeatures = arcpy.Parameter(displayName="Input Base Features", name="base_Features", datatype="GPFeatureLayer", parameterType="Required", direction="Input")
 updatedFeatures = arcpy.Parameter(displayName="Input Updated Features", name="updated_Features", datatype="GPFeatureLayer", parameterType="Required", direction="Input")
 linearUnit = arcpy.Parameter(displayName="Search Distance", name="search_distance", datatype="GPLinearUnit", parameterType="Required", direction="Input")
 fieldCompare = arcpy.Parameter(displayName="Compare Fields", name="compareFields", datatype="GPValueTable", parameterType="Optional", direction="Input")
 paramNames = [baseFeatures.name, updatedFeatures.name]
 fieldCompare.parameterDependencies = paramNames
 fieldCompare.columns = [['Field', 'Base Fields'], ['Field', 'Updated Fields']]
 geometryOutput = arcpy.Parameter(displayName="Geometry Changes Output", name="newandnochange_Features", datatype="GPBoolean", parameterType="Optional", direction="Input")
 attributeChangeOutput = arcpy.Parameter(displayName="Attribute Changes Output", name="attributechanges_Features", datatype="GPBoolean", parameterType="Optional", direction="Input")
 delAndNewOutput = arcpy.Parameter(displayName="Deleted/New Features", name="delandnew_Features", datatype="GPBoolean", parameterType="Optional", direction="Input")
 params = [baseFeatures, updatedFeatures, linearUnit, fieldCompare, geometryOutput, attributeChangeOutput ,delAndNewOutput]
 return params

I thought that with parameter dependencies I could specify two names, instead it only takes into account the first name I choose in the dependencies list (if Ihave 'baseFeatures.name' first both columns will only have the baseFeatures columns / if I have 'updatedFeatures.name' first it will only have the updatedFeature columns), and I can't "link" one parameter with the desired cloumn.

Does anyone know what am I missing?

PolyGeo
65.5k29 gold badges115 silver badges349 bronze badges
asked Oct 7, 2021 at 22:14

2 Answers 2

4

This is the expected behaviour, which is similar to Dissolve or Summary Statistics tools. You can set one dependency to the extract fields of a table (i.e., feature class as well). If you change fieldCompare.parameterDependencies = paramNames to fieldCompare.parameterDependencies = [baseFeatures.name] presuming you want to list base data's fields to compare and set your columns as fieldCompare.columns = [['Field', 'Base Fields'], ['String', 'Updated Fields']], you will have the correct initial setup.

Following that you need to control Updated Fields from def updateParameters(self, parameters): by checking the state of updatedFeatures variable. This question may help: Updating ValueTable parameter of ArcPy Python Toolbox tool.

UPDATE

The ESRI Community answer that you posted devises a similar approach, removing dependencies, and populating the fields of base... and updated... table fields when layer selections are made for all. However, it may fail if you change your layer selected. I suggest similar approach which might solve this issue as keeping the dependency.

def updateParameters(self, parameters):
 """Modify the values and properties of parameters before internal
 validation is performed. This method is called whenever a parameter
 has been changed."""
 if parameters[1].altered and not parameters[1].hasBeenValidated:
 # Reset the corresponding update field when the "updated..." selection is changed, 
 # if there is existing field(s) in the value table
 if parameters[3].values: 
 parameters[3].values = [[i[0].value, ''] for i in parameters[3].values]
 # Populate the updated side of the value table with the fields from the "updated..."
 parameters[3].filters[1].list = [f.name for f in arcpy.ListFields(parameters[1].value)]
 return 
answered Oct 8, 2021 at 3:12
2
  • Thank you very much for your answer, I definetly made progresses. I was able to force all the columns from my 'updatedFeatures' input parameter table into the Updated Fields column, the problem is I don't want to force it but rather pick them one by one. I want to choose the columns from 'baseFeatures' input parameter table in the Base Fields column and choose the columns from 'updatedFeatures' input parameter table in the Updated Fields column. My goal was to make this like the 'Compare Fields' in the 'Detect Feature Changes' tool. Am I missing something, did I not understand your help? Commented Oct 8, 2021 at 19:33
  • @P-Rosa, see my update above Commented Oct 11, 2021 at 2:06
0

I got a response from the ESRI community that solved the problem.

This is the code:

def getParameterInfo(self):
 """Define parameter definitions"""
 baseFeatures = arcpy.Parameter(displayName="Input Base Features", name="base_Features", datatype="GPFeatureLayer", parameterType="Required", direction="Input")
 updatedFeatures = arcpy.Parameter(displayName="Input Updated Features", name="updated_Features", datatype="GPFeatureLayer", parameterType="Required", direction="Input")
 linearUnit = arcpy.Parameter(displayName="Search Distance", name="search_distance", datatype="GPLinearUnit", parameterType="Required", direction="Input")
 fieldCompare = arcpy.Parameter(displayName="Compare Fields", name="compareFields", datatype="GPValueTable", parameterType="Optional", direction="Input")
 fieldCompare.columns = [['GPString', 'Base Fields'], ['GPString', 'Updated Fields']]
 geometryOutput = arcpy.Parameter(displayName="Geometry Changes Output", name="newandnochange_Features", datatype="GPBoolean", parameterType="Optional", direction="Input")
 attributeChangeOutput = arcpy.Parameter(displayName="Attribute Changes Output", name="attributechanges_Features", datatype="GPBoolean", parameterType="Optional", direction="Input")
 delAndNewOutput = arcpy.Parameter(displayName="Deleted/New Features", name="delandnew_Features", datatype="GPBoolean", parameterType="Optional", direction="Input")
 params = [baseFeatures, updatedFeatures, linearUnit, fieldCompare, geometryOutput, attributeChangeOutput ,delAndNewOutput]
 return params
def isLicensed(self):
 """Set whether tool is licensed to execute."""
 return True
def updateParameters(self, parameters):
 """Modify the values and properties of parameters before internal
 validation is performed. This method is called whenever a parameter
 has been changed."""
 if parameters[0].valueAsText and parameters[1].valueAsText:
 desc_b = arcpy.Describe(parameters[0].value)
 desc_u = arcpy.Describe(parameters[1].value)
 parameters[3].filters[0].list = [field.name for field in desc_b.fields]
 parameters[3].filters[1].list = [field.name for field in desc_u.fields]
 return

I will now finish this question.

Midavalo
30k11 gold badges53 silver badges108 bronze badges
answered Oct 8, 2021 at 20:56

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.