Select to view content in your preferred language

Python Toolbox to create buffer layer

784
6
Jump to solution
4 weeks ago
BrandonPrice1
Frequent Contributor

Hello,

Can somebody advise me on how to code this properly? The below script was attempted using google AI snippets to create an in memory buffer layer of 500 feet based on the feature currently selected in the map. It throws an error when trying to run it. Also, if there is any advice on creating an editable layer from all features that intersect the buffer. Eventually, I plan to publish everything as a GP service.

import arcpy
import arcpy.mp

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


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):
        param0 = arcpy.Parameter(
            displayName="Input Feature Layer",
            name="in_features",
            datatype="GPFeatureLayer",
            parameterType="Required",
            direction="Input")

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

        return [param0, param1]

    def execute(self, parameters, messages):
        in_features = parameters[0].valueAsText
        out_buffer_name = parameters[1].valueAsText

        # Set the scratch workspace for temporary data
        arcpy.env.scratchWorkspace = "in_memory" 

        # Create the full path for the output buffer feature class
        out_buffer_fc = arcpy.ValidateTableName(out_buffer_name, arcpy.env.scratchWorkspace)

        # Buffer the selected features
        arcpy.Buffer_analysis(in_features, out_buffer_fc, "500 Feet")
        messages.addMessage(f"Buffer created: {out_buffer_fc}")

        # Add the buffer layer to the map (for ArcGIS Pro)
        aprx = arcpy.mp.ArcGISProject("CURRENT")
        active_map = aprx.activeMap
        
        # Make a feature layer from the buffered output
        arcpy.management.MakeFeatureLayer(out_buffer_fc, out_buffer_name)

        new_layer = arcpy.mp.Layer(out_buffer_name) # Create a Layer object from the temporary layer
        
        # Add the layer to the active map
        active_map.addLayer(new_layer)
        messages.addMessage(f"Buffer layer '{out_buffer_name}' added to the map.")

        return

-Brandon

0 Kudos
1 Solution

Accepted Solutions
HaydenWelch
MVP Regular Contributor

mp.Layer is a class that you can't initialize. It's a representation of a program object. You can use it to type hint a return value, but if you want to create a layer, you need to use MakeFeatureLayer and assign the result to a variable.

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

        return [in_features, out_buffer_name]

    def execute(self, parameters: list[arcpy.Parameter], messages):
        params = {p.name: p for p in parameters}
        in_features = params['in_features'].value
        out_buffer_name = params['out_buffer_name'].value
        aprx = arcpy.mp.ArcGISProject("CURRENT")
        
        with arcpy.EnvManager(workspace='memory'):
            # Create the full path for the output buffer feature class
            out_buffer_fc = arcpy.ValidateTableName(out_buffer_name)

            # Buffer the selected features
            arcpy.analysis.Buffer(in_features, out_buffer_fc, "500 Feet")
            
            # Make a feature layer from the buffered output
            new_layer = arcpy.management.MakeFeatureLayer(out_buffer_fc, out_buffer_name)[0]
            arcpy.AddMessage(f"Buffer created: {out_buffer_fc}")
        
        # Add the layer to the active map
        aprx.activeMap.addLayer(new_layer)
        arcpy.AddMessage(f"Buffer layer '{out_buffer_name}' added to the map.")

Just a sidenote: with the workspace set to memory, the buffer layer will exist only in memory. You can accept a full derived layer path as a Parameter input if that's what you really want to do.

View solution in original post

6 Replies
DanPatterson
MVP Esteemed Contributor

and what would the error be?


... sort of retired...
0 Kudos
TylerT
by
Frequent Contributor

Hi @BrandonPrice1,

in-memory
 is legacy workspace.  You might try memory depending on your ArcGIS version.  

See memory docs here: https://pro.arcgis.com/en/pro-app/latest/help/analysis/geoprocessing/basics/the-in-memory-workspace....

Tyler

0 Kudos
BrandonPrice1
Frequent Contributor

My apologies. Below is the error message. I tried changing in_memory to memory and got this same error.

BrandonPrice1_0-1756160012140.png

 

HaydenWelch
MVP Regular Contributor

mp.Layer is a class that you can't initialize. It's a representation of a program object. You can use it to type hint a return value, but if you want to create a layer, you need to use MakeFeatureLayer and assign the result to a variable.

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

        return [in_features, out_buffer_name]

    def execute(self, parameters: list[arcpy.Parameter], messages):
        params = {p.name: p for p in parameters}
        in_features = params['in_features'].value
        out_buffer_name = params['out_buffer_name'].value
        aprx = arcpy.mp.ArcGISProject("CURRENT")
        
        with arcpy.EnvManager(workspace='memory'):
            # Create the full path for the output buffer feature class
            out_buffer_fc = arcpy.ValidateTableName(out_buffer_name)

            # Buffer the selected features
            arcpy.analysis.Buffer(in_features, out_buffer_fc, "500 Feet")
            
            # Make a feature layer from the buffered output
            new_layer = arcpy.management.MakeFeatureLayer(out_buffer_fc, out_buffer_name)[0]
            arcpy.AddMessage(f"Buffer created: {out_buffer_fc}")
        
        # Add the layer to the active map
        aprx.activeMap.addLayer(new_layer)
        arcpy.AddMessage(f"Buffer layer '{out_buffer_name}' added to the map.")

Just a sidenote: with the workspace set to memory, the buffer layer will exist only in memory. You can accept a full derived layer path as a Parameter input if that's what you really want to do.

BrandonPrice1
Frequent Contributor

Thanks again, this buffer tool intended to be used as a geoprocessing service. So, the newly generated buffer layer would be added to a webmap rather than a ArcGIS Pro Project. I will try using your sample and tweak it for online use.

0 Kudos
BrandonPrice1
Frequent Contributor

Thanks. I appreciate it.

0 Kudos