You could go about this in a few ways. One way to do it without Zero_Qualms' suggestion of ET_GeoWizards and with only an ArcView licence is to create your buffer polygons just as you have done. Then iterate over the buffer polygons, pulling out their geometry and build a new feature class using the geometry but cast it as a polyline instead. See these sections of the documentation to help you (if needed) with reading and writing geometries in ArcPy (scroll down for examples).
The alternative is to write a script to create the line without creating a buffer to copy first. You will need to read the geometries of your lines and progress from point to point, calculating the bearing at each step and then calculating the offset location of your buffer-line. This should be straightforward with a bit of basic vector maths and trig. You can calculate bother the left and right side of the line at the same time. You just need to ensure that the right-side (assuming a clockwise winding) points are added to your polyline so they are in sequential order following the entire set of left-hand points and in the reverse direction. You could do this by having two lists of points and then reverse the order of your right-hand point list before appending it to the lefthand points list to make your line.
While the buffer wizard is not exposed through ArcPy, geometries do expose the buffer method so the following works to create multiple ring buffers:
import arcpy
def MultiRingBuffer(ringDistance, ringCount, inputLayer, outputLayer):
buffers = []
cursor = arcpy.SearchCursor(inputLayer)
for inputFeature in cursor:
sourceOid = inputFeature.getValue("OBJECTID")
currentBuffers = dict()
buffers.append(currentBuffers)
prevBuffer = inputFeature.Shape
for multiple in range(1, ringCount + 1):
distance = multiple * ringDistance
bufferedGeom = inputFeature.Shape.buffer(distance)
bufGeom = bufferedGeom.difference(prevBuffer)
prevBuffer = bufferedGeom
row = dict()
row["sourceOid"] = sourceOid
row["distance"] = distance
row["SHAPE"] = bufGeom
currentBuffers[distance] = row
del cursor
cursor = arcpy.InsertCursor(outputLayer)
for ringBuffers in buffers:
for feature in ringBuffers.values():
row = cursor.newRow()
for k in feature.keys():
if k == "SHAPE":
row.Shape = feature[k]
else:
row.setValue(k, feature[k])
cursor.insertRow(row)
del cursor
if __name__ == '__main__':
MultiRingBuffer(10, 10, "c:\\temp\\test.gdb\\buffertest", "c:\\temp\\test.gdb\\bufferout")
print("Complete")
For each source feature, we create a dictionary to store each ring buffer. Each of these buffers is a dictionary with a few values - the source OID, the distance, and the buffer geometry. We then create an insert cursor and create features in the output table for each ring buffer of each input feature.
Edit: I have tested this and with 3 simple features, where the gp tool takes over a minute, this script takes ~1s once arcpy has finished importing.
Edit 2: Fixed a couple of bugs - firstly, the difference call was removing the previous ring rather than all previous rings. Secondly, I wasn't adding the ring to the currentBuffer so it wasn't getting added later...
Edit 3: Handled the shape field not being 'SHAPE' in the output featureclass. Added cleanup of cursor objects.
Best Answer
You could try the Flat-end line buffer tool. I made it for a specific purpose for which it works fine. I sometimes merge the result to create a polygon from. The tool should work fine with 10.0. Have not tested in 10.1.
EDIT: There is a few parameters that can be set; distance, mitered or beveled, extend line ends. (for my purposes I needed to extend the line ends so i made that an option) Because it was made for specific purpose you should be aware that it does not resolve crossing lines (as I mentioned in my comment above). If anyone is interested I can illustrate what this looks like. Basically, resulting crossing lines have to be resolved manually before creating a polygon or polygon will result in a non-simple geometry.
I thought I would add some visuals to show what this basically does: Result: Result as polygon (also use a custom tool for that):