5 votos

Obtener información de una herramienta en ArcObjects

Tengo la siguiente situación en un complemento de ArcMap que estoy creando:

Este complemento contiene un formulario en el que el usuario debe hacer clic en un botón y, a continuación, dibujar una polilínea en el mapa (el formulario no es modal). La polilínea es necesaria en el formulario para su posterior procesamiento.

Ahora he implementado esto utilizando una herramienta que hereda de ESRI.ArcGIS.Desktop.AddIns.Tool y utiliza un RubberLineClass en el OnMouseDown evento. La herramienta se activa en el evento OnClick del botón. Todo esto funciona, y el usuario puede dibujar la polilínea.

El problema es obtener la polilínea de la herramienta. Yo estaba pensando en tener la herramienta de añadir la polilínea como un elemento gráfico en el mapa, y en la forma de escuchar a la ItemAdded evento en IActiveView. Desafortunadamente, este evento sólo se produce cuando maplayers se añaden. En hace funcionan con elementos en el PageLayout, pero si añado el elemento a este, las coordenadas de la polilínea se alteran. Además, esto se siente un poco torpe.

Entonces, la pregunta es: ¿hay una forma mejor de obtener información de una herramienta? ¿O hay una manera de dibujar una polilínea en el mapa sin utilizar una herramienta?

Tal vez no sea relevante, pero aquí está el código de todos modos:

// Activate the tool
var documentBars = ((IDocument)ArcMap.Document).CommandBars;
var cmdItem = documentBars.Find(new UIDClass { Value = ThisAddIn.IDs.PolylineTool });
ArcMap.Application.CurrentTool = cmdItem;

// The tool's OnMouseDown event
protected override void OnMouseDown(MouseEventArgs arg)
{
    var rubberBand = new RubberLineClass();
    var geometry = rubberBand.TrackNew(ArcMap.Document.ActiveView.ScreenDisplay, new SimpleLineSymbolClass { Color = new RgbColorClass { Red = 255 } });
    geometry.SpatialReference = ArcMap.Document.FocusMap.SpatialReference;

    if (!geometry.IsEmpty)
    {
        var container = (IGraphicsContainer)ArcMap.Document.FocusMap;
        container.AddElement(new LineElementClass { Geometry = geometry }, 0);
    }
}

1 votos

En algunas situaciones me ha resultado más fácil cambiar el caso de uso: El usuario dibuja un gráfico de polilínea utilizando la herramienta out-of-the-box. El usuario selecciona el gráfico. El usuario pulsa el botón personalizado. El sistema verifica que se ha seleccionado un gráfico de polilínea y lo utiliza para el procesamiento.

0 votos

@KirkKuykendall Sí, me planteé hacerlo así, pero añade lógica extra que hay que manejar. Por ejemplo, más de un gráfico podría estar en el mapa, un usuario necesita para eliminar el gráfico después.

5voto

John Kramlich Puntos 286

Acabo de mirar un poco de código antiguo y la forma en que hice esto es:

  1. Mi formulario era en realidad una ventana acoplable, no estoy seguro de que eso suponga una diferencia.

  2. En el evento New() de la ventana obtengo un handle de la herramienta y luego añado un handle del evento:

        ' Get a handle on tool control and listener for event
        m_tool = ESRI.ArcGIS.Desktop.AddIns.AddIn.FromID(Of HER_AddIn.btnGetHERID)("GDI_HER_AddIn_btnGetHERID")
        AddHandler m_tool.HERIDGrabbed, AddressOf captureHERID
  3. En la ventana acoplable hay una sub privada que se ocupa del evento, en puede caso captureHERID . Lo primero que hace este sub es obtener la geometría del punto de una propiedad expuesta públicamente que había creado para la herramienta.

    pPoint = m_tool.OnPointClicked

  4. Mi código para la herramienta es el siguiente:

    Imports ESRI.ArcGIS.Geometry Imports ESRI.ArcGIS.ArcMapUI Imports ESRI.ArcGIS.Display

    Public Class btnGetHERID Inherits ESRI.ArcGIS.Desktop.AddIns.Tool

    ''' <summary>Declare an Event called HERIDGrabbed</summary>
    ''' <remarks>This is the event that is listened out for in the dkwEditHER window</remarks>
    Public Event HERIDGrabbed()
    
    ''' <summary>The coordinate of the location clicked by the user.</summary>
    ''' <remarks>The XY coordinates are in map units.</remarks>
    Private m_Point As IPoint
    
    Public Sub New()
        ' Initialise point object and set to a default 0,0 location
        m_Point = New PointClass
        m_Point.PutCoords(0, 0)
    End Sub
    
    Protected Overrides Sub Finalize()
        m_Point = Nothing
        MyBase.Finalize()
    End Sub
    
    ''' <summary>Enables tool.</summary>
    ''' <remarks>This tool is always available but does not exist on any toolbar.</remarks>
    Protected Overrides Sub OnUpdate()
        Me.Enabled = True
    End Sub
    
    ''' <summary>Captures location clicked in map units.</summary>
    ''' <param name="arg">MouseEventAgs</param>
    ''' <remarks>Raises the event HERIDGrabbed</remarks>
    Protected Overrides Sub OnMouseDown(arg As ESRI.ArcGIS.Desktop.AddIns.Tool.MouseEventArgs)
    
        ' Convert location clicked into real world map units and store
        Dim pMXdocument As IMxDocument
        pMXdocument = My.ArcMap.Document
        Dim pScreenDisplay As IScreenDisplay
        pScreenDisplay = pMXdocument.ActiveView.ScreenDisplay
        m_Point = pScreenDisplay.DisplayTransformation.ToMapPoint(arg.X, arg.Y)
    
        ' Raise the event
        RaiseEvent HERIDGrabbed()
        MyBase.OnMouseDown(arg)
    End Sub
    
    ''' <summary>A public function that returns the location clicked.</summary>
    ''' <returns>An IPoint object</returns>
    ''' <remarks>During initialization this is set to 0,0 so the return point is always a valid point object.</remarks>
    Public Function OnPointClicked() As IPoint
        OnPointClicked = m_Point
    End Function

    End Class

Asegúrate de eliminar el manejador de eventos del formulario cuando lo cierres.

0 votos

Genial, no sabía que el FromID() método

1voto

lepole Puntos 1588

Creo que un enfoque más sencillo es crear la geometría utilizando la función INewLineFeedback interfaz. El método stop devuelve la forma. Mucho más fácil que implementar un montón de controladores de eventos. Usted debe ser capaz de implementar esto en su herramienta.

Alternativamente, utilice una de las herramientas de selección (línea, rectángulo, polígono) para dibujar la forma, pero en lugar de crear una selección, simplemente agarre la forma. Aquí tiene un ejemplo de Esri: Extensión de selección personalizada

Probablemente sea mejor coger la forma del evento OnDoubleClick en tu herramienta personalizada y hacer lo que necesites con ella. Hay interfaces similares para los otros tipos de geometría.

También relacionado: Obtener la geometría de la herramienta de selección de lazo

0 votos

Parece que sólo sustituye a la clase Rubberband, ¿estoy en lo cierto? Todavía necesitaría una herramienta personalizada para agarrar el evento mousedown.

0 votos

Sí, creo que no he entendido tu problema. Pensé que estabas teniendo problemas para adquirir la forma de una herramienta personalizada. Si usted tiene una referencia a la forma de la herramienta que implementó entonces ¿cuál es el problema? Depende de usted si desea dibujar en el mapa o no, pero si usted tiene la forma a continuación, sólo pasar a lo largo del resto del programa desde el ratón hacia abajo evento.

0 votos

El problema era cómo hacer referencia a la geometría en una forma personalizada (es decir, otra clase que la herramienta). Hornbydd dio la respuesta a eso.

i-Ciencias.com

I-Ciencias es una comunidad de estudiantes y amantes de la ciencia en la que puedes resolver tus problemas y dudas.
Puedes consultar las preguntas de otros usuarios, hacer tus propias preguntas o resolver las de los demás.

Powered by:

X