1

I had a custom drawing tool which is available in samples of arcGIS 10.1 Sdk for .Net. When we draw a line or any perimeter on the map, and right click on the line and go to properties, it display a line length. EDITED:

I want to send that line length in to my textbox which is on another form. Any directions? what to do? How to do?

 using ESRI.ArcGIS.Carto;
 using System;
 using System.Drawing;
 using System.Runtime.InteropServices;
 using ESRI.ArcGIS.ADF.BaseClasses;
 using ESRI.ArcGIS.ADF.CATIDs;
 using ESRI.ArcGIS.Framework;
 using ESRI.ArcGIS.ArcMapUI;
 using System.Windows.Forms;

 namespace CustomTool

{

/// <summary>
/// Summary description for DrawGraphicLine.
/// </summary>
[Guid("001c57ca-c292-459d-95a7-9984d78d0d93")]
[ClassInterface(ClassInterfaceType.None)]
[ProgId("CustomTool.DrawGraphicLine")]
public sealed class DrawGraphicLine : BaseTool
{
    #region COM Registration Function(s)
    [ComRegisterFunction()]
    [ComVisible(false)]
    static void RegisterFunction(Type registerType)
    {
        // Required for ArcGIS Component Category Registrar support
        ArcGISCategoryRegistration(registerType);

        //
        // TODO: Add any COM registration code here
        //
    }

    [ComUnregisterFunction()]
    [ComVisible(false)]
    static void UnregisterFunction(Type registerType)
    {
        // Required for ArcGIS Component Category Registrar support
        ArcGISCategoryUnregistration(registerType);

        //
        // TODO: Add any COM unregistration code here
        //
    }

    #region ArcGIS Component Category Registrar generated code
    /// <summary>
    /// Required method for ArcGIS Component Category registration -
    /// Do not modify the contents of this method with the code editor.
    /// </summary>
    private static void ArcGISCategoryRegistration(Type registerType)
    {
        string regKey = string.Format("HKEY_CLASSES_ROOT\\CLSID\\{{{0}}}", registerType.GUID);
        MxCommands.Register(regKey);

    }
    /// <summary>
    /// Required method for ArcGIS Component Category unregistration -
    /// Do not modify the contents of this method with the code editor.
    /// </summary>
    private static void ArcGISCategoryUnregistration(Type registerType)
    {
        string regKey = string.Format("HKEY_CLASSES_ROOT\\CLSID\\{{{0}}}", registerType.GUID);
        MxCommands.Unregister(regKey);

    }

    #endregion
    #endregion

    private IApplication m_application;
    public DrawGraphicLine()
    {
        //
        // TODO: Define values for the public properties
        //
        base.m_category = "Walkthroughs"; //localizable text 
        base.m_caption = "Draw Graphic Line";  //localizable text 
        base.m_message = "";  //localizable text
        base.m_toolTip = "Draws a graphic line in the map window of ArcMap.";  //localizable text
        base.m_name = "CustomTool_DrawGraphicLine";   //unique id, non-localizable (e.g. "MyCategory_ArcMapTool")
        try
        {
            //
            // TODO: change resource name if necessary
            //
            string bitmapResourceName = GetType().Name + ".bmp";
            base.m_bitmap = new Bitmap(GetType(), bitmapResourceName);
            base.m_cursor = new System.Windows.Forms.Cursor(GetType(), GetType().Name + ".cur");
        }
        catch (Exception ex)
        {
            System.Diagnostics.Trace.WriteLine(ex.Message, "Invalid Bitmap");
        }
    }

    #region Overriden Class Methods

    /// <summary>
    /// Occurs when this tool is created
    /// </summary>
    /// <param name="hook">Instance of the application</param>
    public override void OnCreate(object hook)
    {
        m_application = hook as IApplication;

        //Disable if it is not ArcMap
        if (hook is IMxApplication)
            base.m_enabled = true;
        else
            base.m_enabled = false;

        // TODO:  Add other initialization code
    }

    /// <summary>
    /// Occurs when this tool is clicked
    /// </summary>
    public override void OnClick()
    {
        // TODO: Add DrawGraphicLine.OnClick implementation
    }

    public override void OnMouseDown(int Button, int Shift, int X, int Y)
    {
        //TODO: Add DrawGraphicLine_VB.OnMouseDown implementation

        //Get the active view from the application object (ie. hook)
        IActiveView activeView = GetActiveViewFromArcMap(m_application);

        //Get the polyline object from the users mouse clicks
        IPolyline polyline = GetPolylineFromMouseClicks(activeView);

        //Make a color to draw the polyline 
        IRgbColor rgbColor = new RgbColorClass();
        rgbColor.Red = 255; 

        //Add the users drawn graphics as persistent on the map
        AddGraphicToMap(activeView.FocusMap, polyline, rgbColor, rgbColor);

        //Only redraw the portion of the active view that contains the graphics 
        activeView.PartialRefresh(esriViewDrawPhase.esriViewGraphics, null, null);
    }

    public override void OnMouseMove(int Button, int Shift, int X, int Y)
    {
        // TODO:  Add DrawGraphicLine.OnMouseMove implementation
    }

    public override void OnMouseUp(int Button, int Shift, int X, int Y)
    {
        // TODO:  Add DrawGraphicLine.OnMouseUp implementation
    }
    #endregion

    //#### ArcGIS Snippets ####

    #region "Get ActiveView from ArcMap"

    ///<summary>Get ActiveView from ArcMap</summary>
    ///  
    ///<param name="application">An IApplication interface that is the ArcMap application.</param>
    ///   
    ///<returns>An IActiveView interface.</returns>
    ///   
    ///<remarks></remarks>
    public IActiveView GetActiveViewFromArcMap(IApplication application)
    {
      if (application == null)
      {
        return null;
      }
      IMxDocument mxDocument = application.Document as IMxDocument; // Dynamic Cast
      IActiveView activeView = mxDocument.ActiveView;

      return activeView;
    }
    #endregion

    #region "Get Polyline From Mouse Clicks"

    ///<summary>
    ///Create a polyline geometry object using the RubberBand.TrackNew method when a user click the mouse on the map control. 
    ///</summary>
    ///<param name="activeView">An ESRI.ArcGIS.Carto.IActiveView interface that will user will interace with to draw a polyline.</param>
    ///<returns>An ESRI.ArcGIS.Geometry.IPolyline interface that is the polyline the user drew</returns>
    ///<remarks>Double click the left mouse button to end tracking the polyline.</remarks>
    public IPolyline GetPolylineFromMouseClicks(IActiveView activeView)
    {

      IScreenDisplay screenDisplay = activeView.ScreenDisplay;

      IRubberBand rubberBand = new RubberLineClass();
      IGeometry geometry = rubberBand.TrackNew(screenDisplay, null);

      IPolyline polyline = (IPolyline)geometry;

      return polyline;

    }
    #endregion

    #region "Add Graphic to Map"

    ///<summary>Draw a specified graphic on the map using the supplied colors.</summary>
    ///      
    ///<param name="map">An IMap interface.</param>
    ///<param name="geometry">An IGeometry interface. It can be of the geometry type: esriGeometryPoint, esriGeometryPolyline, or esriGeometryPolygon.</param>
    ///<param name="rgbColor">An IRgbColor interface. The color to draw the geometry.</param>
    ///<param name="outlineRgbColor">An IRgbColor interface. For those geometry's with an outline it will be this color.</param>
    ///      
    ///<remarks>Calling this function will not automatically make the graphics appear in the map area. Refresh the map area after after calling this function with Methods like IActiveView.Refresh or IActiveView.PartialRefresh.</remarks>
    public void AddGraphicToMap(IMap map, IGeometry geometry, IRgbColor rgbColor, IRgbColor outlineRgbColor)
    {
      IGraphicsContainer graphicsContainer = (IGraphicsContainer)map; // Explicit Cast
      IElement element = null;
      if ((geometry.GeometryType) == esriGeometryType.esriGeometryPoint)
      {
        // Marker symbols
        ISimpleMarkerSymbol simpleMarkerSymbol = new SimpleMarkerSymbolClass();
        simpleMarkerSymbol.Color = rgbColor;
        simpleMarkerSymbol.Outline = true;
        simpleMarkerSymbol.OutlineColor = outlineRgbColor;
        simpleMarkerSymbol.Size = 15;
        simpleMarkerSymbol.Style = esriSimpleMarkerStyle.esriSMSCircle;

        IMarkerElement markerElement = new MarkerElementClass();
        markerElement.Symbol = simpleMarkerSymbol;
        element = (IElement)markerElement; // Explicit Cast
      }
      else if ((geometry.GeometryType) == esriGeometryType.esriGeometryPolyline)
      {
        //  Line elements
        ISimpleLineSymbol simpleLineSymbol = new SimpleLineSymbolClass();
        simpleLineSymbol.Color = rgbColor;
        simpleLineSymbol.Style = esriSimpleLineStyle.esriSLSSolid;
        simpleLineSymbol.Width = 5;

        ILineElement lineElement = new LineElementClass();
        lineElement.Symbol = simpleLineSymbol;
        element = (IElement)lineElement; // Explicit Cast
      }
      else if ((geometry.GeometryType) == esriGeometryType.esriGeometryPolygon)
      {
        // Polygon elements
        ISimpleFillSymbol simpleFillSymbol = new SimpleFillSymbolClass();
        simpleFillSymbol.Color = rgbColor;
        simpleFillSymbol.Style = esriSimpleFillStyle.esriSFSForwardDiagonal;
        IFillShapeElement fillShapeElement = new PolygonElementClass();
        fillShapeElement.Symbol = simpleFillSymbol;
        element = (IElement)fillShapeElement; // Explicit Cast
      }
      if (!(element == null))
      {
        element.Geometry = geometry;
        graphicsContainer.AddElement(element, 0);
      }
    }
    #endregion
}

}

6
  • 1
    Where is this textbox? On a toolbar, form, panel? Need a bit more info... DO you want to send this information when you have finished drawing the line or do you want to create another tool that grabs that length and writes it to a textbox?
    – Hornbydd
    Commented Apr 19, 2015 at 20:07
  • Do you already have a form for this tool? The simplest way is to set the properties of the textbox to 'public' (default is private) then use my_form.textbox1.Text = my_line.length.ToString() to put it into the text box. Otherwise create a public void TextBoxUpdate(double Length) function on the form to do the work. Some code would really help us understand where you're at! Commented Apr 19, 2015 at 23:17
  • @hornbydd Textbox is on a seprate form. This form opens with an addin button. I want to send information when user have finished drawing the line. Commented Apr 20, 2015 at 10:39
  • @michaelMiles-Stimson Actually i know this method of exporting information from one form to another but i dont know how to access that line and its length functionality in arcobject. In your words,how to create this my_line.Length in arcobjects? i dont know what reference or class to use and i could find it on internet either . A headway start would be good enough for me. just a hint. i am not a beginner of C# , yes i am beginner at arcobjects Commented Apr 20, 2015 at 10:43
  • Show us the code that you have that draws the line, it is not clear that you are drawing a graphic on the map or an actual feature in a layer.
    – Hornbydd
    Commented Apr 20, 2015 at 13:24

2 Answers 2

2

OK, in the function GetPolylineFromMouseClicks just before the return statement you could do something like:

myForm.myTextbox.Text = polyline.Length.ToString

I'm assuming the RubberLineClass picks up on the coordinate system of the dataframe. But that leads to another question. If you dataframe is WGS84 then length in decimal degrees is not going to mean much to anyone so is your data projected, just something to consider?

In one of your comments you say "form opens with an addin button", is this another button? If so you need to work out how to hook into the modeless form, which it has to be if you are interacting with other parts of the application interface. It may be more appropriate to open the form on the onClick() event of the tool code above?

1
  • its the simplest solution ever i got anywhere. Wish i could vote it up for others Commented Apr 20, 2015 at 20:51
2

In addition to the previous fine answer:

polyline.SpatialReference = ArcMap.Document.FocusMap.SpatialReference; 
ISpatialReferenceFactory3 SRfact = (ISpatialReferenceFactory3)new SpatialReferenceEnvironment();
ISpatialReference SR = SRfact.CreateSpatialReference(EPSG_of_Projected_CoSys);
polyline.Project(SR);
myForm.myTextbox.Text = polyline.Length.ToString();

As Hornbydd indicated the RubberBand collects the maps' spatial reference, if you want that in a different coordinate system (for example, if the map is in DD and you want metres) then project the line. I have encountered circumstances where the measurement was wanted in geographic but that situation is very rare, usually it's the other way around.

p.s. I would have made this a comment except I wanted it formatted and there's too many words, +1 Hornbydd!

1
  • 1
    Ha... but you provided the code to project the polyline, so you get a vote too! :)
    – Hornbydd
    Commented Apr 20, 2015 at 21:39

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.