Select to view content in your preferred language

How to re-code python toolbox to work on the web

194
2
2 weeks ago
ShareUser
Esri Community Manager

Hello,

I created a python toolbox with assistance from this community that now works in ArcGIS Pro. The tool creates a 500-foot in memory buffer layer around a selected parcel and then creates another memory layer of the parcels that intersect the buffer. The script applies layer files to the resulting layers for styling. At this point, I want it to publish it and have it work in an Experience Builder Analysis widget. The resulting memory layers will need to now be permanent layers though it seems (I read memory layers can only be created in ArcGIS Pro). As a result, I was just thinking of tweaking the toolbox somehow to use the ArcGIS API for Python to create and add the layers to the current web map. The layers created could be hosted on the same ArcGIS Server as the GP Service and the GP service could overwrite the layers in ArcGIS Server each time it's ran. Anyway, any input on how this code can be changed to accomplish this is greatly appreciated.

import arcpy

class Toolbox:
    def __init__(self):
        self.label = "Custom Buffer Tools"
        self.alias = "CustomBuffer"
        self.tools = [BufferSelectedFeatures]


class BufferSelectedFeatures(object):
    def __init__(self):
        self.label = "Buffer Selected Features"
        self.description = "Creates a 500-foot buffer around selected features."
        self.canRunInBackground = False

    def getParameterInfo(self):
        in_features = arcpy.Parameter(
            name="in_features",
            displayName="Input Feature Layer",
            datatype="GPFeatureLayer",
            parameterType="Required",
            direction="Input")

        out_buffer_name = arcpy.Parameter(
            name="out_buffer_name",
            displayName="Output Buffer Layer Name",
            datatype="GPString",
            parameterType="Required",
            direction="Input")
        out_buffer_name.value = "Selected_Feature_Buffer" # Default name

        out_intersect_name = arcpy.Parameter(
            name="out_intersect_name",
            displayName="Output Intersect Layer Name",
            datatype="GPString",
            parameterType="Required",
            direction="Input")
        out_intersect_name.value = "Intersected_Features" # Default name

        #input_parcel_name = arcpy.Parameter(
            #name="input_parcel_name",
            #displayName="Output Parcel Layer Name",
            #datatype="GPString",
            #parameterType="Required",
            #direction="Input")
        #input_parcel_name.value = "Input_Parcel" # Default name

        return [in_features, out_buffer_name, out_intersect_name]

    def execute(self, parameters: list[arcpy.Parameter], messages):
        params = {p.name: p for p in parameters}
        in_features = params['in_features'].value
        out_intersect_name = params['out_intersect_name'].value
        out_buffer_name = params['out_buffer_name'].value
        #input_parcel_name = params['input_parcel_name'].value
        buffer_layer_file = r"C:\Documents\ArcGIS\Projects\Existing Land Use Generator\Existing_LU_Buffers (500ft).lyrx"
        existing_LU_layer_file = r"C:\Documents\ArcGIS\Projects\Existing Land Use Generator\Existing_LU_Parcels.lyrx"
        aprx = arcpy.mp.ArcGISProject("CURRENT")
        m = aprx.listMaps("Map")[0] # Assuming "Map" is the name of your map
        parcel_layer = m.listLayers("ASSR_PARCELS")[0] # Replace "MyInputLayerName" with your layer's name
        #field_mapping = "UseDesc UseDescription"
                  
        with arcpy.EnvManager(workspace='memory'):
            # Create the full path for the output buffer feature class
            out_intersect_fc = arcpy.ValidateTableName(out_intersect_name)
            out_buffer_fc = arcpy.ValidateTableName(out_buffer_name)
            #in_features_fc = arcpy.ValidateTableName(input_parcel_name)
            # Buffer the selected features
            arcpy.analysis.Buffer(in_features, out_buffer_fc, "500 Feet")
            
            # Make a feature layer from the buffered output and style it using layer file
            new_layer = arcpy.management.MakeFeatureLayer(out_buffer_fc, out_buffer_name)[0]
            final_layer = arcpy.management.ApplySymbologyFromLayer(new_layer, buffer_layer_file)[0]
            arcpy.AddMessage(f"Buffer created: {out_buffer_fc}")
            arcpy.SelectLayerByLocation_management(parcel_layer, "INTERSECT", new_layer, "", "NEW_SELECTION", "")
            arcpy.CopyFeatures_management(parcel_layer, out_intersect_fc)
            parcel_intersect = arcpy.management.MakeFeatureLayer(out_intersect_fc, out_intersect_name)[0]
            parcel_intersect_symbolized = arcpy.management.ApplySymbologyFromLayer(parcel_intersect, existing_LU_layer_file)[0]
            arcpy.SelectLayerByAttribute_management(parcel_layer, "CLEAR_SELECTION")
            #interest_parcel = arcpy.management.MakeFeatureLayer(in_features, input_parcel_name)
            #arcpy.SelectLayerByAttribute_management(in_features, "CLEAR_SELECTION")
            #arcpy.CopyFeatures_management(in_features_fc, in_features_fc)
            #interest_parcel = arcpy.management.MakeFeatureLayer(in_features_fc, in_features)[0]
             
        # Add the layer to the active map
        aprx.activeMap.addLayer(parcel_intersect_symbolized)
        aprx.activeMap.addLayer(final_layer)
        #aprx.activeMap.addLayer(interest_parcel)
        arcpy.AddMessage(f"Buffer layer '{out_buffer_name}' added to the map.")

BrandonPrice1_0-1758676216828.pngBrandonPrice1_1-1758676300741.png

 

0 Kudos
2 Replies
ShareUser
Esri Community Manager

I believe you need to write to a GDB and not in-memory, then publish as hosted feature service.

0 Kudos
DavidPike
MVP Notable Contributor

You don't really need to think about where the output is stored server-side unless you really want to update an SDE table.  Publishing the GP tool wrangles the output paths so it can be a temp output added as a map result each time.

Set your tool output type to a Feature Class, ensure direction is Output.   Then run it in Pro with a local output.  Publish it to Server and that copy the REST service endpoint to the GP tool input.


0 Kudos