4

Building on Inside buffer with attributes in ArcGIS?, I'd like to be able to create multiple ring buffers, while retaining (and possibly dissolving on) attribute values. How can this be done?

2 Answers 2

5

OK, how I did this, is loop through creating ring buffers on objects, and saving the output as a new featureclass in a standlone datasets collection. I then merged the featureclasses, like so:

tmp_merge = "path to area"\+ "tmp_merge"  
final_out_path_agg = final_staging + "_Agg"
final_out_path_simp = final_staging +  "_Simp"

#check if files exist and delete if they do; assume nothing
if (arcpy.Exists(tmp_merge)):
    arcpy.Delete_management(tmp_merge)   

#set up folder to search for polygon data
arcpy.env.workspace = scratchDB + "mytmpBuff.gdb/Polygons/"
#collate FC
fcs = arcpy.ListFeatureClasses()
L = []
count = 0
try:
    for fc in fcs:
        #append to array ready for merging
        L.append(fc)
        count = count + 1
except:
    print "Error collating FeatureClasses."

try:
    if count > 1:
        arcpy.Merge_management(L, tmp_merge)
    elif count == 0:
        arcpy.AddMessage("No FeatureClass Polygons located.")
        arcpy.AddMessage("Error collating FeatureClasses.")
        sys.exit(-1) 
except:
    arcpy.AddMessage("Error merging FeatureClasses.")   

Then dissolved them

#overlaps dissolved
arcpy.Dissolve_management(tmp_merge, final_out_path_agg, "Name", [["RunID","FIRST"],["AltiLwr","FIRST"],["AltUpr","FIRST"],["TimeSl","FIRST"],["ConcentrationBand","FIRST"],["ConcLvl","FIRST"],["IsC","FIRST"]])  
arcpy.DeleteField_management(final_out_path_agg, "NAME") 

The buffers are created in a loop and stored in arcpy.env.workspace = scratchDB + "mytmpBuff.gdb/Polygons/" before I later loop through them.

It works, or it does if I have understood your issue correctly!

3

Below is my answer. Although it bears little resemblance now to Hairy's example, it was only by stepping through and understanding his code that I was able to find my own solution, so thank you!

multi-ring-buffer.py: Create multiple ring buffers, keeping named attributes of parent feature class.

Process:

  • create inside only buffer for each of the specifed buffer widths
  • store buffer width used as an attribute
  • merge all buffers into a single feature class, ensuring largest width first so narrower ones are drawn on top

Usage:

multi-ring-buffer [feature class]  [workspace]  [output feature class]  [widths list]  [attributes to keep]

multi-ring-buffer R:\data.gdb\Foobar_ply  X:\maps\buffers.gdb  Foobar_rings   50,-50,-100,-300,-600  NAME,TYPE

Workspace must exist. The width and attribute parameters must be comma separated and have no spaces. Requires Arcgis 10, Arcinfo license level.

(c) 2021 Environment Yukon, [email protected] Licensed under the MIT license: http://www.opensource.org/licenses/MIT

import arcpy
from arcpy import env

in_fc = arcpy.GetParameterAsText(0)                   # features to buffer
wspace = arcpy.GetParameterAsText(1)                # output workspace
out_fc = arcpy.GetParameterAsText(2)                 # finished result
distances = arcpy.GetParameterAsText(3).split(',')  # list of buffer widths 
# parse list of attributes to keep into semi-colon separated as expected by buffer tool
dissolveFields = arcpy.GetParameterAsText(4).replace(',',';')

env.workspace = wspace

sideType = "OUTSIDE_ONLY"
endType = "ROUND"
dissolveType = "LIST"

buffered_fcs = []
for distance in distances:
    buf_fc = arcpy.ValidateTableName('xxx_' + out_fc + distance)
    print("...buffering {0} into {1} with width {2}".format(in_fc, buf_fc, distance))
    
    arcpy.Buffer_analysis(in_fc, buf_fc, distance, sideType, endType, dissolveType, dissolveFields)
    
    # store buffer width as attribute value
    arcpy.AddField_management(buf_fc, 'Width', "TEXT", "", "", 16)
    arcpy.CalculateField_management(buf_fc, 'Width', distance, "PYTHON")
    
    buffered_fcs.append(buf_fc)

# arrange buffers from largest to smallest width
# so the draw order is correct after merging
buffered_fcs.sort()
buffered_fcs.reverse() 

print("...Merging intermediate buffers into {0}".format(out_fc))
arcpy.Merge_management(buffered_fcs, out_fc)

# remove temporary intermediate files
print("...Removing intermediate files")
for fc in arcpy.ListFeatureClasses('xxx_*'):
    arcpy.Delete_management(fc)

In source code management at https://github.com/envygeo/arcplus/tree/master/ArcToolbox/Scripts

The resulting ring buffers displayed with multi-field unique values in arcmap:

Multiple ring buffers displayed with multi-field unique attributes

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.