Saturday, May 16, 2009

The ESRI Generic Get Position Tool

ESRI's ArcGIS Desktop product includes the applications ArcCatalog, ArcMap, ArcScene and ArcGlobe.  The user interfaces of all four applications can be heavily customized by developers, for example, a developer can deploy custom toolbars and buttons.

A button (or command in ESRI terminology) is a COM class that implements the ICommand interface. Some commands require geographic interaction, for example, clicking on a country in a world map.  These commands must implement the ITool interface.

Normally, developers create sets of commands that are specific to each project.  In this article I will discuss an out-of-the-box command called Generic Get Point Tool that can be used for map/globe interaction. Using this command in future projects may reduce your development time.

To demonstrate this command I have created an ArcGIS Engine-based windows application sample using Microsoft .Net Framework 2.0.  The application consists of a map, an invisible toolbar and a button that will activate the Generic Get Point Tool.  After the map is clicked, a message box will display the map coordinates of the clicked location and then deactivate the tool.

The sample windows application (C#) was created using Microsoft Visual Studio 2005.  It consists of a map control, toolbar control, license control and a button.  The map control is assigned to the toolbar control's buddy property and the map control's is assigned a map document to load at runtime.

image 

When the form loads, the Generic Get Point Tool is added to the toolbar and then by casting the command to the IToolPositionInitializer the form is assigned as the callback (because it supports IToolPositionCallback).

image

When the button is clicked the Generic Get Point Tool is located on the toolbar and then assigned as the current tool.  This essentially activates the tool and deactivates the previously active tool (if any).

image

When the user clicks on the map display with the Generic Get Point Tool activated, the command will called the MouseClicked method on the IToolPositionCallback interface.  In the sample, the form implements this interface and displays a message box displaying the map coordinates.  Rather than leaving the tool active, setting IToolbarControl::CurrentTool (or IMapControl::CurrentTool) to null effectively deactivate the tool.

image

The sample code follows:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;

using ESRI.ArcGIS.Controls;
using ESRI.ArcGIS.esriSystem;
using ESRI.ArcGIS.SystemUI;
using ESRI.ArcGIS.Geometry;

namespace WindowsApplication1 {
    public partial class Form1 : Form, IToolPositionCallback{
        public Form1() {
            InitializeComponent();
        }
        private void Form1_Load(object sender, EventArgs e) {
            // Hide ESRI Toolbar
            this.axToolbarControl1.Hide();

            // Add Generic Get Point Tool
            UID uid = new UIDClass();
            uid.Value = "{30DBCBEF-951E-4904-89DE-5A5F1AF571EE}";
            IToolbarControl toolbarControl = (IToolbarControl)this.axToolbarControl1.Object;
            toolbarControl.AddItem(uid, -1, -1, false, -1, esriCommandStyles.esriCommandStyleIconOnly);

            // Find Generic Get Point Tool on Toolbar
            int index = toolbarControl.Find(uid);
            IToolbarItem toolbarItem = toolbarControl.GetItem(index);
            ICommand command = toolbarItem.Command;

            // Assign Callback to Generic Get Point Tool
            IToolPositionInitializer toolPositionInitializer = (IToolPositionInitializer)command;
            toolPositionInitializer.Initialize(this, -1);
        }
        private void Button_Click(object sender, EventArgs e) {
            if (sender == this.buttonGetPoint) {
                // Find Generic Get Point Tool
                UID uid = new UIDClass();
                uid.Value = "{30DBCBEF-951E-4904-89DE-5A5F1AF571EE}";
                IToolbarControl toolbarControl = (IToolbarControl)this.axToolbarControl1.Object;
                int index = toolbarControl.Find(uid);
                IToolbarItem toolbarItem = toolbarControl.GetItem(index);
                ICommand command = toolbarItem.Command;
                ITool tool = (ITool)command;

                // Set Generic Get Point Tool as the current tool
                toolbarControl.CurrentTool = tool;
            }
        }
        #region IToolPositionCallback Members
        public void Deactivated() { }
        public void MouseClicked(int lCookie, int button, int shift, int X, int Y, double mapX, double mapY,
            ISpatialReference pSpace) {
            // Display Message
            string message = string.Format(
                "Map location" + Environment.NewLine +
                "X: {0}" + Environment.NewLine +
                "Y: {1}",
                mapX.ToString(),
                mapY.ToString());
            MessageBox.Show(message, "Test", MessageBoxButtons.OK, MessageBoxIcon.Information);

            // Deactivate Generic Get Point Tool
            IToolbarControl toolbarControl = (IToolbarControl)this.axToolbarControl1.Object;
            toolbarControl.CurrentTool = null;
        }
        #endregion
    }
} 

No comments:

Post a Comment