Hi all, I am trying to figure out a way to add my outputs to the display after my python toolbox runs. I've tried multiple ways but can't seem to get it. Do I need to add the outputs as a parameter for this to occur? How would you go about it. Here is my code below.
import arcpy
import pandas as pd
from arcpy.sa import *
class Toolbox(object):
def __init__(self):
self.label = "Mapping Trees Model"
self.alias = "mapping trees"
# List of tool classes associated with this toolbox
self.tools = [MappingTrees]
class MappingTrees(object):
def __init__(self):
self.label = "Mapping Trees Model"
self.description = "This model analyzes information from a raster with tree data such as tree height, canopy cover percent, etc. for an area of interest defined by the user. "
def getParameterInfo(self):
#Define the parameters
Extent = arcpy.Parameter(
displayName = "Define Extent",
name = "Extent",
datatype = "GPExtent",
parameterType = "Required",
direction = "Input")
Identify_Workspace = arcpy.Parameter(
displayName = "Identify Workspace",
name = "Identify_Workspace",
datatype = "DEWorkspace",
parameterType = "Required",
direction = "Input")
Study_Area = arcpy.Parameter(
displayName="Study Area",
name="Study_Area",
datatype="GPFeatureLayer",
parameterType="Required",
direction="Input")
Study_Area.controlCLSID = "{60061247-BCA8-473E-A7AF-A2026DDE1C2D}"
Base_Raster = arcpy.Parameter(
displayName="Base Tree Raster (such as tree height, canopy cover percentage, etc.)",
name="Base_Raster",
datatype="GPRasterLayer",
parameterType="Required",
direction="Input")
#Base_Raster.filter.type = "ValueList"
dBASE_file = arcpy.Parameter(
displayName = "Class Ranges (dBASE file)",
name = "dBASE_file",
datatype = "GPTableView",
parameterType = "Required",
direction = "Input")
## Patches = arcpy.Parameter(
## displayName = "Raster to Polygon",
## name = "Patches",
## datatype = "GPLayer",
## parameter = "Derived",
## direction = "Output")
parameters = [Extent, Identify_Workspace, Study_Area, Base_Raster, dBASE_file]
return parameters
def isLicensed(self):
try:
if arcpy.CheckExtension("Spatial") != "Available":
raise Exception
else:
arcpy.CheckOutExtension("Spatial")
except Exception:
arcpy.AddMessage('Spatial Analyst Extension not available')
return False # tool cannot be executed
return True # tool can be executed
def updateParameters(self, parameters):
return
def updateMessages(self, parameters):
return
def execute(self, parameters, messages):
#allow tool to overwrite the layers in the file being used
arcpy.env.overwriteOutput == True
#Make it so I can use the parameters in the tool
Extent = parameters[0].valueAsText
Identify_Workspace = parameters[1].valueAsText
Study_Area = parameters[2].valueAsText
Base_Raster = parameters[3].valueAsText
dBASE_file = parameters[4].valueAsText
#Define workspace
arcpy.env.workspace = Identify_Workspace
# Extract by Mask: extract out the study area out of the base raster
Extract_Mask = "Extract_Raster.tif"
Extract_Mask1 = arcpy.sa.ExtractByMask(Base_Raster, Study_Area, "INSIDE")
Extract_Mask1.save(Extract_Mask)
# Reclassify: classify a raster with the range of what you would like it to be
array = arcpy.da.TableToNumPyArray(dBASE_file, "*")
df = pd.DataFrame(array)
class_list = df.values.tolist()
for i in range(len(class_list)):
class_list[i] = class_list[i][1:-1]
myRemapRange = arcpy.sa.RemapRange(class_list)
User_Reclassified_Raster = "User_Reclassified_Raster.tif"
reclassified_raster = arcpy.sa.Reclassify(Extract_Mask1, "Value", myRemapRange, "NODATA")
reclassified_raster.save(User_Reclassified_Raster)
# Add Field: add the field Range to the reclassified raster
# to help user know what ranges go with what classified value
arcpy.management.AddField(User_Reclassified_Raster, "Range", "TEXT", field_alias = "Height Range")
# Join Field: join the from and to fields from the dBASE file
arcpy.management.JoinField(User_Reclassified_Raster, "Value", dBASE_file, "OUT",["FROM_", "TO"])
# Calculate Field
arcpy.management.CalculateField(User_Reclassified_Raster,"Range", "\"!FROM_! - !TO!\"")
# Delete Field
arcpy.management.DeleteField(User_Reclassified_Raster, ["FROM_", "TO"])
#List the fields in the Study Area polygon and if it does not have the fild ID, add it
fields = arcpy.ListFields(Study_Area)
if "Id" not in fields:
arcpy.management.AddField(Study_Area, "Id", "LONG")
arcpy.management.CalculateField(Study_Area, "Id", 0)
# Tabulate Area: calculate the area of each range of heights, etc.
Tabulate_Area = "Tabulate_Area.dbf"
arcpy.sa.TabulateArea(User_Reclassified_Raster, "Range", Study_Area, "Id", Tabulate_Area, User_Reclassified_Raster, "CLASSES_AS_FIELDS")
# Join, Add Field, Calculate Field, Delete Field: the tabulate area table to the reclassified raster, then add and calculate
# the field Area so one knows what field they are looking at, Delete the field "ID_0"
arcpy.management.JoinField(User_Reclassified_Raster, "Range", Tabulate_Area, "RANGE", ["ID_0"])
arcpy.management.AddField(User_Reclassified_Raster, "Area", "DOUBLE")
arcpy.management.CalculateField(User_Reclassified_Raster, "Area", "!ID_0!")
arcpy.management.DeleteField(User_Reclassified_Raster, "ID_0")
# Raster to Polygon: convert the reclassified raster to polygons
R2P = "R2P"
arcpy.conversion.RasterToPolygon(User_Reclassified_Raster, R2P,"NO_SIMPLIFY", "Range")
# Dissolve: combine all the polygons together that touch
Dissolve_Polys = "Dissolve_Polys"
arcpy.management.Dissolve(R2P, Dissolve_Polys, "", "", "SINGLE_PART")
#Eliminate: smooth out the polygons
Patches = "Patches"
arcpy.management.EliminatePolygonPart(Dissolve_Polys, Patches, "AREA", 1000)
# Zonal Statistics: calculate the statistics (min, max, and mean) of the tree values
ZonalStats = "ZonalStats.dbf"
arcpy.sa.ZonalStatisticsAsTable(Patches, "ORIG_FID", Base_Raster, ZonalStats, "DATA", "MIN_MAX_MEAN")
# Join Field: join the zonal stats fields to the smoothed out polygons
arcpy.management.JoinField(Patches, "ORIG_FID", ZonalStats, "ORIG_FID", ["AREA", "MIN", "MAX", "MEAN"])
arcpy.management.DeleteField(Patches, ["Id", "ORIG_FID"])
arcpy.management.AddField(Patches, "Acres", "DOUBLE")
arcpy.management.CalculateGeometryAttributes(Patches, [["Acres","AREA"]], area_unit="ACRES_US")
# Delete: delete the following layers:
arcpy.management.Delete(Extract_Mask1)
arcpy.management.Delete(R2P)
arcpy.management.Delete(Dissolve_Polys)
arcpy.management.Delete(ZonalStats)
arcpy.management.Delete(Tabulate_Area)
c_project=arcpy.mp.ArcGISProject("CURRENT")
return
def postExecute(self, parameters):
return
Hi @HeatherDulaney1 ,
Could you make these changes and try:
1.
def getParameterInfo(self):
#Define the parameters
Patches = arcpy.Parameter(
displayName="Final Output Patches",
name="Patches",
datatype="DEFeatureClass",
parameterType="Derived",
direction="Output")
parameters = [Extent, Identify_Workspace, Study_Area, Base_Raster, dBASE_file, Patches]
return parameters
2.
def execute(self, parameters, messages):
#Eliminate: smooth out the polygons
Patches = os.path.join(arcpy.env.workspace, "Patches.shp")
arcpy.management.EliminatePolygonPart(Dissolve_Polys, Patches, "AREA", 1000)
# Set the Patches parameter as output
arcpy.SetParameterAsText(5, Patches)
3.
def postExecute(self, parameters):
patches_layer = parameters[5].valueAsText # The "Patches" parameter defined above
# Access the current project and map
aprx = arcpy.mp.ArcGISProject("CURRENT")
active_map = aprx.activeMap
# Add the output feature class as a layer
if patches_layer:
active_map.addDataFromPath(patches_layer)
arcpy.AddMessage(f"Added {patches_layer} to the map.")
return