Select to view content in your preferred language

ESRI.ArcGIS.AnalysisTools.MultipleRingBuffer

1792
6
Jump to solution
02-12-2014 01:32 AM
JohnStallings
Occasional Contributor
Ok... First off I am a first time user of forums EVER, so as you might imagine I have racked my brain to no end with not luck whatsoever. Also, I am not a very good programmer, just thought I should insert that in case some of you programming wizards are wondering why this code look so terrible.

Here is the setup;
I need for my user to be able to input multiple distances for a buffer (thus the Multiple Ring Buffer Tool)

I am using a text box a list box and a add button. Once the action button (Buffer) is activated the numbers in the list box are converted to a List(of Double).

Where my problem comes into play is the .Distances property. If my user enters 500 <list box row 0> and 1000 <list box row 1>
The buffer generates a single buffer with a distance of 500.1 instead of 2 entries per Feature i.e. 1 - 500, 2 - 1000.

I have tried what I think to be everything. Look at my code below; and I will explain more after the code.

<Code>

Public Sub MultipleRingBuffer(ByVal UBuffer As List(Of Double))
        Dim GP As Geoprocessor = New Geoprocessor()
        GP.OverwriteOutput = True
        Dim out As String = "RISK_BUFFER_" & FCName 'FCName is populated from an earlier process in the program.
        Dim look As String = """" & String.Join(",", UBuffer.ToArray) & """"


        '' Create the tool process object.
        Dim bufferTool As ESRI.ArcGIS.AnalysisTools.MultipleRingBuffer = New ESRI.ArcGIS.AnalysisTools.MultipleRingBuffer

        With bufferTool
            .Input_Features = Open.OpenFeatureClassFromString(path & name & ".gdb\" & FCName)
            .Output_Feature_class = path & name & ".gdb\" & out
            .Distances = look
            .Buffer_Unit = "Feet"
            .Field_Name = "INPUT_DISTANCES"
            .Dissolve_Option = "NONE"
        End With
      


        RunTool(GP, bufferTool, Nothing)

    End Sub

    Private Sub RunTool(ByVal geoprocessor As Geoprocessor, ByVal process As IGPProcess, ByVal TC As ITrackCancel)

        geoprocessor.OverwriteOutput = True
        Try
            geoprocessor.Execute(process, Nothing)
            'ReturnMessages(geoprocessor)

        Catch err As Exception
            'Console.WriteLine(err.Message)
            MessageBox.Show(err.Message)
        End Try
    End Sub

</Code>

look is the variable that I am using to push to the .Distances Property. Also Notice the UBuffer is being received from another part of the program.

What I have tried for the .Distances;
1. Passing UBuffer directly - .Distances = UBuffer (Did not Work)
2. Dim look As String = """" & String.Join(" ", UBuffer.ToArray) & """" Notice the <space>
3. Dim look As String = String.Join(",", UBuffer.ToArray)  Notice the Missing """" at the begin and end of the string
4. Dim look As String = """" & String.Join(";", UBuffer.ToArray) & """" Notice the ";"
5. Dim look as Object = UBuffer - multiple iterations of this

This can go on and on... I suspect I am either completely wrong by using the above look variable or I have something minor wrong.

Thank you!
0 Kudos
1 Solution

Accepted Solutions
JohnStallings
Occasional Contributor
The answer was slapping me in the face the entire time.

I was using geoprocessor.Execute

Use geoprocessor.ExecuteAsync

View solution in original post

0 Kudos
6 Replies
KenBuja
MVP Esteemed Contributor
In my experience, the first thing to do when you run into issues coding a geoprocessing tool is to run it manually. When it runs successfully, take a look at the executing statement to see what the parameters should be. I ran the Multiple Ring Buffer and got this as the result

Messages
Executing: MultipleRingBuffer sample_test C:\Default.gdb\sample_test_MultipleRingBuff 500;1000 Meters distance NONE FULL
Start Time: Wed Feb 12 08:39:34 2014
Running script MultipleRingBuffer...
Completed script MultipleRingBuffer...
Succeeded at Wed Feb 12 08:39:51 2014 (Elapsed Time: 17.00 seconds)


In this case, the distances have to be separated by a semicolon.
0 Kudos
JohnStallings
Occasional Contributor
If you look at number 4 I had already tried that and I receive a Com Error. Which has me wondering if I am having some sort of conflict.
In the same Solution I have;

ESRI.ArcGIS.Geoprocessing
&
ESRI.ArcGIS.Geoprocessor

I looked at the error from the JIT so I could get a full picture and here it is, or at least part of it:

************** Exception Text **************
System.Runtime.InteropServices.COMException (0x80004005): Error HRESULT E_FAIL has been returned from a call to a COM component.
at ESRI.ArcGIS.Geoprocessing.GeoProcessorClass.Execute(String Name, IVariantArray ipValues, ITrackCancel pTrackCancel)
at ESRI.ArcGIS.Geoprocessor.Geoprocessor.ExecuteInner(IGPProcess process, ITrackCancel trackCancel, IGeoProcessor igp, IVariantArray iva)
at ESRI.ArcGIS.Geoprocessor.Geoprocessor.Execute(IGPProcess process, ITrackCancel trackCancel)

I Suspect something is not being passed correctly, either through the Geoprocessor or the IGPProcess.
0 Kudos
JohnStallings
Occasional Contributor
By the way, thank you for taking the time to look into this error for me, now I know for sure it is the semicolon. Now I need to figure out what I suspect to be the real error.

Thank you again!
0 Kudos
KenBuja
MVP Esteemed Contributor
Have you verified that the variable "look" is what you expected it to be?
0 Kudos
JohnStallings
Occasional Contributor
Yes Sir.

I might ultimately have to contact ESRI directly, I am exploring every rabbit hole to no end. what I am looking into right now has me scratching my head a little.

If you look at the Desktop Help for Multiple Ring Buffer (it is a Python Example), however it shows multiple distances being passed into the Distances property.
However

if you look here (Path might be different for you)
C:\Program Files (x86)\ArcGIS\Desktop10.2\ArcToolbox\Scripts
<MultiRingBuffer.py>

Look at this it seems that each distance is ran separately then merged into a single FC at the end.

# Loop through each distance creating a new layer and then buffering the input.
        #  Set the step progressor if there are > 1 rings
        if len(distList) > 1:
            gp.SetProgressor("step", "", 0, len(distList))
            stepProg = True
        else:
            gp.SetProgressor("default")
            stepProg = False

        bufferedList = []

        # Buffer the input for each buffer distance.  If the fieldName is different than
        #  the default, add a new field and calculate the proper value
        for dist in distList:
            if stepProg:
                gp.SetProgressorPosition()
            gp.SetProgressorLabel(msgBuffRings + str(dist) + "...")
            bufDistance = "%s %s" % (dist, unit)
            bufOutput = gp.Buffer_analysis(input, gp.CreateUniqueName("buffer", scratchWks),
                                           bufDistance, sideType, "", dissolveOption).getOutput(0)
            if fieldName.lower() != "buff_dist":
                gp.AddField_management(bufOutput, fieldName, "double")
                gp.CalculateField_management(bufOutput, fieldName, dist, "PYTHON")
            bufferedList.append(bufOutput)

        gp.ResetProgressor()
        gp.SetProgressor("default")
        gp.SetProgressorLabel(msgMergeRings)

This is the current rabbit hole I am chasing.
0 Kudos
JohnStallings
Occasional Contributor
The answer was slapping me in the face the entire time.

I was using geoprocessor.Execute

Use geoprocessor.ExecuteAsync
0 Kudos