ArcObjects Library Reference  

BufferDlg

About the Create a geoprocessing tool to buffer a layer and retrieve messages Sample

[C#]

BufferDlg.cs

using System;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Runtime.InteropServices;
using ESRI.ArcGIS.ADF.BaseClasses;
using ESRI.ArcGIS.ADF.CATIDs;
using ESRI.ArcGIS.Controls;
using ESRI.ArcGIS.Carto;
using ESRI.ArcGIS.esriSystem;
using ESRI.ArcGIS.Geoprocessor;
using ESRI.ArcGIS.Geoprocessing;
using ESRI.ArcGIS.AnalysisTools;

namespace GpBufferLayer
{
  public partial class BufferDlg : Form
  {
    //in order to scroll the messages textbox to the bottom we must import this Win32 call
    [DllImport("user32.dll")]
    private static extern int PostMessage(IntPtr wnd,
                                          uint Msg,
                                          IntPtr wParam,
                                          IntPtr lParam);

    private IHookHelper m_hookHelper = null;
    private const uint WM_VSCROLL = 0x0115;
    private const uint SB_BOTTOM = 7;

    public BufferDlg(IHookHelper hookHelper)
    {
      InitializeComponent();

      m_hookHelper = hookHelper;
    }

    private void bufferDlg_Load(object sender, EventArgs e)
    {
      if (null == m_hookHelper || null == m_hookHelper.Hook || 0 == m_hookHelper.FocusMap.LayerCount)
        return;

      //load all the feature layers in the map to the layers combo
      IEnumLayer layers = GetLayers();
      layers.Reset();
      ILayer layer = null;
      while ((layer = layers.Next()) != null)
      {
        cboLayers.Items.Add(layer.Name);
      }
      //select the first layer
      if (cboLayers.Items.Count > 0)
        cboLayers.SelectedIndex = 0;

      string tempDir = System.IO.Path.GetTempPath();
      txtOutputPath.Text = System.IO.Path.Combine(tempDir,((string)cboLayers.SelectedItem  + "_buffer.shp"));

      //set the default units of the buffer
      int units = Convert.ToInt32(m_hookHelper.FocusMap.MapUnits);
      cboUnits.SelectedIndex = units;
    }

    private void btnOutputLayer_Click(object sender, EventArgs e)
    {
      //set the output layer
      SaveFileDialog saveDlg = new SaveFileDialog();
      saveDlg.CheckPathExists = true;
      saveDlg.Filter = "Shapefile (*.shp)|*.shp";
      saveDlg.OverwritePrompt = true;
      saveDlg.Title = "Output Layer";
      saveDlg.RestoreDirectory = true;
      saveDlg.FileName = (string)cboLayers.SelectedItem  + "_buffer.shp";

      DialogResult dr = saveDlg.ShowDialog();
      if (dr == DialogResult.OK)
        txtOutputPath.Text = saveDlg.FileName;
    }

    private void btnBuffer_Click(object sender, EventArgs e)
    {
      //make sure that all parameters are okay
      double bufferDistance;
      double.TryParse(txtBufferDistance.Text, out bufferDistance);
      if (0.0 == bufferDistance)
      {
        MessageBox.Show("Bad buffer distance!");
        return;
      }

      if (!System.IO.Directory.Exists(System.IO.Path.GetDirectoryName(txtOutputPath.Text)) ||
        ".shp" != System.IO.Path.GetExtension(txtOutputPath.Text))
      {
        MessageBox.Show("Bad output filename!");
        return;
      }

      if (m_hookHelper.FocusMap.LayerCount == 0)
        return;

      //get the layer from the map
      IFeatureLayer layer = GetFeatureLayer((string)cboLayers.SelectedItem);
      if (null == layer)
      {
        txtMessages.Text += "Layer " + (string)cboLayers.SelectedItem + "cannot be found!\r\n";
        return;
      }

      //scroll the textbox to the bottom
      ScrollToBottom();
      //add message to the messages box
      txtMessages.Text += "Buffering layer: " + layer.Name + "\r\n";

      txtMessages.Text += "\r\nGet the geoprocessor. This might take a few seconds...\r\n";
      txtMessages.Update();
      //get an instance of the geoprocessor
      Geoprocessor gp = new Geoprocessor();
      gp.OverwriteOutput = true;
      txtMessages.Text += "Buffering...\r\n";
      txtMessages.Update();

      //create a new instance of a buffer tool
      ESRI.ArcGIS.AnalysisTools.Buffer buffer = new ESRI.ArcGIS.AnalysisTools.Buffer(layer, txtOutputPath.Text, Convert.ToString(bufferDistance) + " " + (string)cboUnits.SelectedItem);
      
      //execute the buffer tool (very easy :-))
      IGeoProcessorResult results = (IGeoProcessorResult)gp.Execute(buffer, null);
      if (results.Status != esriJobStatus.esriJobSucceeded)
      {
        txtMessages.Text += "Failed to buffer layer: " + layer.Name + "\r\n";
      }
      txtMessages.Text += ReturnMessages(gp);
      //scroll the textbox to the bottom
      ScrollToBottom();

      txtMessages.Text += "\r\nDone.\r\n";
      txtMessages.Text += "-----------------------------------------------------------------------------------------\r\n";
      //scroll the textbox to the bottom
      ScrollToBottom();

    }

    private string ReturnMessages(Geoprocessor gp)
    {
      StringBuilder sb = new StringBuilder();
      if (gp.MessageCount > 0)
      {
        for (int Count = 0; Count <= gp.MessageCount - 1; Count++)
        {
          System.Diagnostics.Trace.WriteLine(gp.GetMessage(Count));
          sb.AppendFormat("{0}\n", gp.GetMessage(Count));
        }
      }
      return sb.ToString();
    }

    private IFeatureLayer GetFeatureLayer(string layerName)
    {
      //get the layers from the maps
      IEnumLayer layers = GetLayers();
      layers.Reset();
 
      ILayer layer = null;
      while ((layer = layers.Next()) != null)
      {
        if (layer.Name == layerName)
          return layer as IFeatureLayer;
      }

      return null;
    }

    private IEnumLayer GetLayers()
    {
      UID uid = new UIDClass();
      uid.Value = "{40A9E885-5533-11d0-98BE-00805F7CED21}";
      IEnumLayer layers = m_hookHelper.FocusMap.get_Layers(uid, true);
      
      return layers;
    }

    private void ScrollToBottom()
    {
      PostMessage((IntPtr)txtMessages.Handle, WM_VSCROLL, (IntPtr)SB_BOTTOM, (IntPtr)IntPtr.Zero);
    }
    private void btnCancel_Click(object sender, EventArgs e)
    {
      this.Close();
    }
  }
}
[Visual Basic .NET]

BufferDlg.vb

Imports Microsoft.VisualBasic
Imports System
Imports System.Drawing
Imports System.Text
Imports System.Windows.Forms
Imports System.Runtime.InteropServices
Imports ESRI.ArcGIS.ADF.BaseClasses
Imports ESRI.ArcGIS.ADF.CATIDs
Imports ESRI.ArcGIS.Controls
Imports ESRI.ArcGIS.Carto
Imports ESRI.ArcGIS.esriSystem
Imports ESRI.ArcGIS.Geoprocessor
Imports ESRI.ArcGIS.Geoprocessing
Imports ESRI.ArcGIS.AnalysisTools

Partial Public Class BufferDlg : Inherits Form
  'in order to scroll the messages textbox to the bottom we must import this Win32 call
  <DllImport("user32.dll")> _
  Private Shared Function PostMessage(ByVal wnd As IntPtr, ByVal Msg As UInteger, ByVal wParam As IntPtr, ByVal lParam As IntPtr) As Integer
  End Function

  Private m_hookHelper As IHookHelper = Nothing
  Private Const WM_VSCROLL As UInteger = &H115
  Private Const SB_BOTTOM As UInteger = 7

  Public Sub New(ByVal hookHelper As IHookHelper)
    InitializeComponent()

    m_hookHelper = hookHelper
  End Sub

  Private Sub bufferDlg_Load(ByVal sender As Object, ByVal e As EventArgs) Handles MyBase.Load
    If Nothing Is m_hookHelper OrElse Nothing Is m_hookHelper.Hook OrElse 0 = m_hookHelper.FocusMap.LayerCount Then
      Return
    End If

    'load all the feature layers in the map to the layers combo
    Dim layers As IEnumLayer = GetLayers()
    layers.Reset()
    Dim layer As ILayer = layers.Next()
    Do While Not layer Is Nothing
      cboLayers.Items.Add(layer.Name)
      layer = layers.Next()
    Loop
    'select the first layer
    If cboLayers.Items.Count > 0 Then
      cboLayers.SelectedIndex = 0
    End If

    Dim tempDir As String = System.IO.Path.GetTempPath()
    txtOutputPath.Text = System.IO.Path.Combine(tempDir, (CStr(cboLayers.SelectedItem) & "_buffer.shp"))

    'set the default units of the buffer
    Dim units As Integer = Convert.ToInt32(m_hookHelper.FocusMap.MapUnits)
    cboUnits.SelectedIndex = units
  End Sub

  Private Sub btnOutputLayer_Click(ByVal sender As Object, ByVal e As EventArgs) Handles btnOutputLayer.Click
    'set the output layer
    Dim saveDlg As SaveFileDialog = New SaveFileDialog()
    saveDlg.CheckPathExists = True
    saveDlg.Filter = "Shapefile (*.shp)|*.shp"
    saveDlg.OverwritePrompt = True
    saveDlg.Title = "Output Layer"
    saveDlg.RestoreDirectory = True
    saveDlg.FileName = CStr(cboLayers.SelectedItem) & "_buffer.shp"

    Dim dr As DialogResult = saveDlg.ShowDialog()
    If dr = System.Windows.Forms.DialogResult.OK Then
      txtOutputPath.Text = saveDlg.FileName
    End If
  End Sub

  Private Sub btnBuffer_Click(ByVal sender As Object, ByVal e As EventArgs) Handles btnBuffer.Click
    'make sure that all parameters are okay
    Dim bufferDistance As Double
    Double.TryParse(txtBufferDistance.Text, bufferDistance)
    If 0.0 = bufferDistance Then
      MessageBox.Show("Bad buffer distance!")
      Return
    End If

    If (Not System.IO.Directory.Exists(System.IO.Path.GetDirectoryName(txtOutputPath.Text))) OrElse ".shp" <> System.IO.Path.GetExtension(txtOutputPath.Text) Then
      MessageBox.Show("Bad output filename!")
      Return
    End If

    If m_hookHelper.FocusMap.LayerCount = 0 Then
      Return
    End If

    'get the layer from the map
    Dim layer As IFeatureLayer = GetFeatureLayer(CStr(cboLayers.SelectedItem))
    If Nothing Is layer Then
      txtMessages.Text &= "Layer " & CStr(cboLayers.SelectedItem) & "cannot be found!" & Constants.vbCrLf
      Return
    End If

    'scroll the textbox to the bottom
    ScrollToBottom()
    'add message to the messages box
    txtMessages.Text &= "Buffering layer: " & layer.Name & Constants.vbCrLf

    txtMessages.Text += Constants.vbCrLf & "Get the geoprocessor. This might take a few seconds..." & Constants.vbCrLf
    txtMessages.Update()
    'get an instance of the geoprocessor
    Dim gp As ESRI.ArcGIS.Geoprocessor.Geoprocessor = New ESRI.ArcGIS.Geoprocessor.Geoprocessor()
    gp.OverwriteOutput = True
    txtMessages.Text &= "Buffering..." & Constants.vbCrLf
    txtMessages.Update()

    'create a new instance of a buffer tool
    Dim buffer As ESRI.ArcGIS.AnalysisTools.Buffer = New ESRI.ArcGIS.AnalysisTools.Buffer(layer, txtOutputPath.Text, CStr(bufferDistance) & " " & CStr(cboUnits.SelectedItem))
    'execute the buffer tool (very easy :-))
    Dim results As IGeoProcessorResult = CType(gp.Execute(buffer, Nothing), IGeoProcessorResult)
    If results.Status <> esriJobStatus.esriJobSucceeded Then
      txtMessages.Text &= "Failed to buffer layer: " & layer.Name & Constants.vbCrLf
    End If
    txtMessages.Text += ReturnMessages(gp)
    'scroll the textbox to the bottom
    ScrollToBottom()

    txtMessages.Text += Constants.vbCrLf & "Done." & Constants.vbCrLf
    txtMessages.Text &= "-----------------------------------------------------------------------------------------" & Constants.vbCrLf
    'scroll the textbox to the bottom
    ScrollToBottom()

  End Sub

  Private Function ReturnMessages(ByVal gp As ESRI.ArcGIS.Geoprocessor.Geoprocessor) As String
    Dim sb As StringBuilder = New StringBuilder()
    If gp.MessageCount > 0 Then
      Dim Count As Integer = 0
      Do While Count <= gp.MessageCount - 1
        System.Diagnostics.Trace.WriteLine(gp.GetMessage(Count))
        sb.AppendFormat("{0}" & Constants.vbLf, gp.GetMessage(Count))
        Count += 1
      Loop
    End If
    Return sb.ToString()
  End Function

  Private Function GetFeatureLayer(ByVal layerName As String) As IFeatureLayer
    'get the layers from the maps
    Dim layers As IEnumLayer = GetLayers()
    layers.Reset()

    Dim layer As ILayer = layers.Next()
    Do While Not layer Is Nothing
      If layer.Name = layerName Then
        Return TryCast(layer, IFeatureLayer)
      End If
      layer = layers.Next()
    Loop

    Return Nothing
  End Function

  Private Function GetLayers() As IEnumLayer
    Dim uid As UID = New UIDClass()
    uid.Value = "{40A9E885-5533-11d0-98BE-00805F7CED21}"
    Dim layers As IEnumLayer = m_hookHelper.FocusMap.Layers(uid, True)

    Return layers
  End Function

  Private Sub ScrollToBottom()
    PostMessage(CType(txtMessages.Handle, IntPtr), WM_VSCROLL, CType(SB_BOTTOM, IntPtr), CType(IntPtr.Zero, IntPtr))
  End Sub
  Private Sub btnCancel_Click(ByVal sender As Object, ByVal e As EventArgs) Handles btnCancel.Click
    Me.Close()
  End Sub
End Class