0

I am trying to build a script tool for my job that takes any vector feature (roads, rails, land cover, water polygons etc) and clips it to selected geocells. The geocells are one feature with a field (ID) that displays the name of each geocell. I have used the blog post here:

https://www.arcgis.com/home/item.html?id=91501d56a92e4534a16054554ac9f6d1

to allow users of the tool to be able to select one or more geocells of their choosing to perform the clip. I want the tool built this way so that essentially any boundary type polygon can be used as the clipping feature where you can select portions of the boundary polygon based on a field value.

Here is my code:

# Import libraries and set environments
import os
import arcpy
from arcpy import env
from arcpy.sa import *
from arcpy.ddd import *
env.overwriteOutput = True
# Set the parameters
InputBoundary = arcpy.GetParameterAsText(0)
InputField = arcpy.GetParameterAsText(1)
InputValue = arcpy.GetParameterAsText(2)
selection = arcpy.SetParameter(3, InputValue)
InputFeature = arcpy.GetParameterAsText(4)
Output = arcpy.GetParameterAsText(5)
# Perform the Clip
arcpy.PairwiseClip_analysis(InputFeature, selection, Output)

As written the tool will fail and say that I am not honoring all of the parameters of the clip analysis. That has to to with having "selection" as the clip feature. If I change "selection" to be "InputBoundary" the tool will work but instead of honoring the selection of individual geocells, the tool is clipping the features to the full extent of all geocells

The GUI of my tool looks like how I want it to and lets me select individual geocells:

Feature Extraction Tool

As described in the link above, I am trying to expand upon the example tool to create a MULTIVALUE parameter choice list from an input feature class/table automatically.

In ArcGIS Pro, that example tool's parameters and code look like this:

as shown here

I have attempted to expand upon that example tool's setup like this:

as shown here

I just want to be able to input a boundary polygon, select certain parts of that polygon, and use that selection to clip out portions of another feature.

PolyGeo
65.5k29 gold badges115 silver badges349 bronze badges
asked Aug 9, 2022 at 17:45
2
  • 1
    Do you really have 6 parameters? I only see 5. If I understand correctly, 'selection' isn't a parameter but rather should be defined as a feature layer of parameter(0) with a query where the field parameter(1) includes the values of parameter(2). Commented Aug 10, 2022 at 16:00
  • @Brennan Yes, I have edited my question to include screenshots of what the parameters look like for the example tool I am attempting to expand from and what the parameters are of my current tool attempt. The example tool uses this script as a part in a larger model builder setup so in the mean time I am going to do the same and see if that provides a solution, however, I would like the whole tool to just run in python Commented Aug 11, 2022 at 14:47

1 Answer 1

1

Save this code as a Python Toolbox (ExtractFeatures.pyt). It should provide the functionality you are describing, and you can re-purpose as needed to work within your model.

# -*- coding: utf-8 -*-
import arcpy
class Toolbox(object):
 def __init__(self):
 """Define the toolbox (the name of the toolbox is the name of the
 .pyt file)."""
 self.label = "Extract Features"
 self.alias = "pytbx"
 # List of tool classes associated with this toolbox
 self.tools = [extractor]
class extractor(object):
 def __init__(self):
 self.label = "Feature Extraction Tool"
 self.description = "Performs a clip based on selected values"
 self.canRunInBackground = False
 def getParameterInfo(self):
 
 InputBoundary = arcpy.Parameter( #0
 displayName="Input Boundary Features",
 name="InputBoundary",
 datatype="GPFeatureLayer",
 parameterType="Required",
 direction="Input")
 InputBoundary.filter.list = ["Polygon"]
 
 InputField = arcpy.Parameter( #1
 displayName="Input Field",
 name="InputField",
 datatype="GPString",
 parameterType="Required",
 direction="Input") 
 
 Values = arcpy.Parameter( #2
 displayName = "Select Values in Field",
 name = "Values",
 datatype="GPString",
 parameterType="Required",
 direction = "Input",
 multiValue = True)
 
 InputFeatures = arcpy.Parameter( #3
 displayName="Input Features to Clip",
 name="InputFeatures",
 datatype="GPFeatureLayer",
 parameterType="Required",
 direction="Input")
 
 Output = arcpy.Parameter( #4
 displayName="Output Feature Class",
 name="Output",
 datatype="DEFeatureClass",
 parameterType="Required",
 direction="Output")
 
 parameters = [InputBoundary,InputField,Values,InputFeatures,Output]
 return parameters
 
 def updateParameters(self, parameters):
 #if InputBoundary is defined/changed, clear subsequent values and populate InputField list
 if parameters[0].value and not parameters[0].hasBeenValidated:
 parameters[1].value = ''
 parameters[1].filter.list = [f.name for f in arcpy.ListFields(parameters[0].value) if f.type not in ['Blob','Geometry']]
 parameters[2].value = None
 parameters[2].filter.list = []
 
 #if InputField is defined/changed, clear and populate Values list
 if parameters[1].value and not parameters[1].hasBeenValidated:
 parameters[2].value = None
 parameters[2].filter.list = list(set(str(row[0]) for row in arcpy.da.SearchCursor(parameters[0].valueAsText, parameters[1].valueAsText)))
 
 return 
 
 def execute(self, parameters, messages):
 
 InputBoundary = parameters[0].valueAsText
 InputField = parameters[1].valueAsText
 Values = parameters[2].values
 InputFeatures = parameters[3].valueAsText
 Output = parameters[4].valueAsText
 
 #Define the selection query based on if InputField is numeric or string
 InType = arcpy.ListFields(InputBoundary,InputField)[0].type
 if InType.lower() in ('string','guid','globalid'):
 query = InputField+" IN ({:s})".format(','.join(f"'{x}'" for x in Values))
 else:
 query = InputField+" IN ({:s})".format(','.join(f"{x}" for x in Values))
 
 #select by attribute and clip
 arcpy.management.SelectLayerByAttribute(InputBoundary, 'NEW_SELECTION', query)
 arcpy.analysis.Clip(InputFeatures, InputBoundary, Output)
 
 return
answered Aug 11, 2022 at 19:33
0

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.