2

I am using ArcGIS Pro.

I have a road shapefile with an attribute named 'Type' which has different values ('Highway', 'Main Road' etc.).

I want to create different buffers based on these values e. g. buffer all objects which are "Type = 'Highways'" by 5 meters, all objects which are "Type = 'Main Roads'" by 3 meters.

Here is my code so far:

roads = r'C:\Users\roads.shp'
arcpy.MakeFeatureLayer_management(roads, 'roads')
    
with arcpy.da.SearchCursor(roads, ['Type']) as cursor:
    for row in cursor:
        if row[0] == 'Highway':
            arcpy.Buffer_analysis(roads, 
                                  r'C:\Users\buffer_highway', 
                                  '5 Meters', "FULL", "ROUND", "LIST")
        elif row[0] == 'Main Road':
            arcpy.Buffer_analysis(roads, 
                                  r'C:\Users\buffer_main_road', 
                                  '3 Meters', "FULL", "ROUND", "LIST")

If I run it, hundreds of buffers are created (the buffer is executed for the whole shapeifle evertytime one of the cursor meets the condition of the if-statement).

I also tried this to buffer each value separately:

if arcpy.SelectData_management(roads, "Type = 'Highway'"):
    arcpy.Buffer_analysis(roads, r'C:\Users\buffer_highway', 
                      "5 Meters" , "FULL")
else:
    pass

But I get this Error:

ExecuteError: Failed to execute. Parameters are not valid.
ERROR 000840: The value is not a Data Element.
ERROR 000840: The value is not a Composite Layer.
Failed to execute (SelectData).

Has anyone a suggestion?

0

2 Answers 2

5

Add a new (number) field to the feature class that holds the buffer distance for each feature. Use the field calculator to populate this new field according to the Type value.

Then when buffering, instead of using a distance value, tell it to use this field instead.

The name of the Buffer parameter is "buffer_distance_or_field". Ie, you can enter either a distance number, or a field name. If you use a field name, it will look up the number in that field for each feature.

See: https://pro.arcgis.com/en/pro-app/latest/tool-reference/analysis/buffer.htm

If the data in the feature class changes regularly and you don't want to have to keep re-calculating the buffer distance values every time you want to create the buffers, you could use a seperate table for the types and distance values to look up, and then join the feature class to this table (instead of adding a new field to the feature class).

2
  • Thank you for your answer. The best way is always the easiest one. I didn't think of that variable. But still, I was looking for a more flexible method, e.g. if I have a world-city point-shapefile and I only want to buffer the cities in the US.
    – Radde1683
    Oct 18, 2022 at 8:13
  • Then select those features first, then run the buffer. Oct 19, 2022 at 0:30
2

I don't think you can use the Geoprocessing Tools as you have, in an "IF" statement in the second example. In the first example, you are telling ArcMap to Buffer the roads everytime if finds a "Main Road" or "Highway" in the Type field of the shapefile.

I don't have access to ArcGIS / Pro to test, but find a workflow below:

  1. Select the highway (using arcpy.SelectLayerByAttribute and arcpy.analysis.Select)

  2. Buffer highway

  3. Select Main Road

  4. Buffer Main Road

  5. Merge all buffered roads to one feature

    hwy = arcpy.management.SelectLayerByAttribute(roads, 'NEW_SELECTION','"type" = "Highway"')
    hwybuf = arcpy.analysis.Buffer(hwy, hwybuf, "5 Meters")
    mainroad = arcpy.management.SelectLayerByAttribute(roads,'NEW_SELECTION','"type" = "Highway"')
    mrbuf = arcpy.analysis.Buffer(mainroad, mrbuf, "3 Meters")
    arcpy.management.Merge(["hwybuf", "mrbuf"],"C:/output/Output.gdb/allroadsbuffer")

As I said, untested, but I think you will get your results by splitting the select by attribute out first, buffer, then merge it back together.

3
  • Thanks, this approach works better. But you have to select the attributes with the arcpy.Select_analysis() function to create a new shapefile, with a WHERE-Clause: where_clause = ' "type" = \'Highway\' '. Using arcpy.management.SelectLayerByAttribute() doesn't work because it literally just selects the values but the buffer is not affected by that selection.
    – Radde1683
    Oct 18, 2022 at 8:16
  • @Radde1683 I guess it depends on how this will be implemented. The "arcpy.SelectLayerAttribute" allows you to still isolate features and run geoprocessing tasks over them. I will amend the answer to include the "arcpy.Select.analysis" GP Tool. Oct 18, 2022 at 22:54
  • I found the error why it didn't work if anybody is interested. The buffer with only the selection didn't work, because I didn't use the layer as the input e.g arcpy.Buffer_analysis("input", ...) but arcpy.Buffer_analysis(input, ...), so the input has to be put in quotes.
    – Radde1683
    Dec 19, 2022 at 9:43

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.