Hello everyone,
I have a script in arcmap which operates on selected blocks on the map and does some calculations and then displays results like this:
I had the script (python toolbox) published as a gp service so I could use it from the geoprocessing wizard. It seems to "validate" ok when I enter the url to the service. It shows absolutely nothing for inputs/outputs/options. I'm using the select widget to select the blocks on the land use layer then clicking the geoprocessing widget then execute.
This is what happens in web appbuilder:
I really have no idea what's going on with it in web appbuilder. I know that in arcmap the script knows to look at the land use layer for selected blocks and then it does its calculations. Not quite sure at the moment how to move forward with getting this working. Any help appreciated.
Thanks
Hi Kevin, I do not know why I was not able to see "set as input to geoprocessing".
So thought I'd update where things are at with this. Getting closer but still not working. I changed the code as follows so that the toolbox has inputs and outputs (code at bottom).
When I use the select widget to select blocks it seems as if the selection is not being used as input to the gp widget.
As you can see from the gp results it is using 33291 blocks in the calculations (the layer has a total of 34646 blocks). So I'm not sure where the 33291 is coming from.
Also I thought I would see "Set as input of geoprocessing" as a select option, but I only see the following:
Any thoughts appreciated as to what I may be missing to get the gp widget to use the selected blocks. Hoping we're getting close. Thanks everyone!
############################################
###Start of class for DiversityIndex toolbox
############################################
class Toolbox(object):
def __init__(self):
"""Define the toolbox (the name of the toolbox is the name of the
.pyt file)."""
self.label = "DiversityIndex"
self.alias = ""
# List of tool classes associated with this toolbox
self.tools = [DiversityIndex]
############################################
###Start of class for DiversityIndex tool
############################################
class DiversityIndex(object):
def __init__(self):
"""Define the tool (tool name is the name of the class)."""
self.label = "Diversity Index"
self.description = "Calculate the land use diversity index based on selected blocks."
self.canRunInBackground = False
def getParameterInfo(self):
#Define parameter definitions
# First parameter
param0 = arcpy.Parameter(
displayName="Input Features",
name="in_features",
datatype="GPFeatureLayer",
parameterType="Required",
direction="Input")
param0.value = 'LandUse_UseCategory'
# Second parameter
param1 = arcpy.Parameter(
displayName="Diversity Index",
name="diversity_index",
datatype="GPDouble",
parameterType="Derived",
direction="Output")
# Third parameter
param2 = arcpy.Parameter(
displayName="Residential Diversity Index",
name="residential_diversity_index",
datatype="GPDouble",
parameterType="Derived",
direction="Output")
# Fourth parameter
param3 = arcpy.Parameter(
displayName="Total Blocks Selected",
name="total_blocks_selected",
datatype="GPLong",
parameterType="Derived",
direction="Output")
# Fifth parameter
param4 = arcpy.Parameter(
displayName="Total Blocks Area",
name="total_blocks_area",
datatype="GPDouble",
parameterType="Derived",
direction="Output")
# Sixth parameter
param5 = arcpy.Parameter(
displayName="Total Residential Blocks Selected",
name="total_residential_blocks_selected",
datatype="GPLong",
parameterType="Derived",
direction="Output")
# Seventh parameter
param6 = arcpy.Parameter(
displayName="Total Residential Blocks Area",
name="total_residential_blocks_area",
datatype="GPDouble",
parameterType="Derived",
direction="Output")
# Eighth parameter
param7 = arcpy.Parameter(
displayName="Note",
name="note",
datatype="GPString",
parameterType="Derived",
direction="Output")
param7.value = 'NOTE: Any blocks with a use category of Invalid are not included in any calculations.'
params = [param0, param1, param2, param3, param4, param5, param6, param7]
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."""
return
def updateMessages(self, parameters):
"""Modify the messages created by internal validation for each tool
parameter. This method is called after internal validation."""
return
def execute(self, parameters, messages):
"""The source code of the tool."""
import numpy as np
try:
arcpy.env.overwriteOutput = True
inFeatures = parameters[0].valueAsText
#Create in memory tables:
arcpy.CreateTable_management("in_memory", "tableSelRecs")
arcpy.AddField_management(r'in_memory\tableSelRecs', "USE_CATEGORY", "TEXT", field_length=35)
arcpy.AddField_management(r'in_memory\tableSelRecs', "SHAPE_Area", "Double")
arcpy.CreateTable_management("in_memory", "tableSumRecs")
arcpy.AddField_management(r'in_memory\tableSumRecs', "USE_CATEGORY", "TEXT", field_length=35)
arcpy.AddField_management(r'in_memory\tableSumRecs', "SHAPE_Area", "Double")
totalArea = 0
totalResArea = 0
totalParcels = 0
totalResParcels = 0
#use da.SearchCursor to access necessary fields from selected records
with arcpy.da.SearchCursor(inFeatures,['USE_CATEGORY','SHAPE@AREA']) as cursor:
#Setup insert cursor to insert selected polygons into tableSelRecs
insCursor = arcpy.da.InsertCursor(r'in_memory\tableSelRecs', ['USE_CATEGORY','SHAPE_Area'])
#Isert selected rows into insCursor; Get total area of selected records; Get a count of total parcels
for row in cursor:
if row[0] != 'Invalid':
insCursor.insertRow((row[0],row[1]))
totalArea += row[1]
totalParcels += 1
#If the block is of a 'Residential' USE_CATEGORY type then add that value into the Residential DI calculation variable
if row[0] in('Residential - Low Density','Residential - Medium Density','Residential - High Density'):
totalResArea += row[1]
totalResParcels += 1
#use summarystatistics against tableSelRecs to get totals per USE_CATEGORY and write results to tableSumRecs
arcpy.Statistics_analysis(r'in_memory\tableSelRecs', r'in_memory\tableSumRecs', [["SHAPE_Area", "SUM"]], "USE_CATEGORY")
with arcpy.da.SearchCursor(r'in_memory\tableSumRecs',['USE_CATEGORY','SUM_SHAPE_Area']) as selCur:
#list to store calculation for each USE_CATEGORY value used in DI calculation
interimValue = [0]
#list to store calculation for each USE_CATEGORY value used in RDI calculation
interimResValue = [0]
for sRow in selCur:
#divide the USE_CATEGORY area by the total community area then square that number & append it to the list
interimValue.append(np.square(sRow[1]/totalArea))
if sRow[0] in('Residential - Low Density','Residential - Medium Density','Residential - High Density'):
interimResValue.append(np.square(sRow[1]/totalResArea))
#sum the values in the list then subtract that value from 1 to get the DI for the selected blocks
DI = 1 - sum(interimValue)
#sum the values in the list then subtract that value from 1 to get the RDI for the selected blocks
RDI = 1 - sum(interimResValue)
parameters[1].value = DI
parameters[2].value = RDI
parameters[3].value = totalParcels
parameters[4].value = totalArea
parameters[5].value = totalResParcels
parameters[6].value = totalResArea
#Delete in memory tables
arcpy.Delete_management(r'in_memory\tableSelRecs')
arcpy.Delete_management(r'in_memory\tableSumRecs')
except arcpy.ExecuteError:
print(arcpy.GetMessages(2))
Get this working? I'm about to start on a similar project!
Hi Kevin, unfortunately as yet I haven't made much more progress from what you see here. It got frustrating on my end trying to troubleshoot this as I do not have permission to publish services in our environment and it requires putting in a helpdesk ticket to IT and it just got bottlenecked with me making repeated requests to republish or refresh the service. So I've put it aside for a bit and am trying to get them to give me permissions to publish services to our dev environment. Sorry I haven't better news for you. Once I'm back on track I'll update this thread.
I'll update this thread with any progress on my end. Thanks!