ArcObjects Library Reference  

MainForm

About the Arranging MOLE graphics using manual decluttering Sample

[C#]

MainForm.cs

using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Data;
using System.IO;
using System.Runtime.InteropServices;

using ESRI.ArcGIS.ADF;
using ESRI.ArcGIS.Carto;
using ESRI.ArcGIS.Controls;
using ESRI.ArcGIS.DefenseSolutions;
using ESRI.ArcGIS.Display;
using ESRI.ArcGIS.esriSystem;
using ESRI.ArcGIS.Geometry;
using ESRI.ArcGIS.SystemUI;


namespace ManualGroupDraw
{
	public sealed partial class MainForm : Form
	{
		#region class private members

		private IMapControl3 m_mapControl = null;
		private Random m_Random = new Random();
		private IMoleGroupElement m_MoleGroup = new MoleGroupElementClass();

		#endregion

		#region Constructor

		public MainForm()
		{
			InitializeComponent();
		}

		#endregion

		#region Form Event Handlers


        private string GetSdkDataPath()
        {
            //get the ArcGIS path from the registry
            Microsoft.Win32.RegistryKey key = Microsoft.Win32.Registry.LocalMachine.OpenSubKey(@"SOFTWARE\ESRI\ArcGIS_SXS_SDK");
            string path = Convert.ToString(key.GetValue("InstallDir"));

            //set the of the logo
            string str = System.IO.Path.Combine(path, @"Samples\data\");

            if (!System.IO.Directory.Exists(str))
            {
                MessageBox.Show("Path :" + str + " does not exist!");
                return string.Empty;
            }

            return str;
        }

		private void MainForm_Load(object sender, EventArgs e)
		{
			// get the MapControl
			m_mapControl = (IMapControl3) axMapControl1.Object;

			// get a map from the SDK sample data
            string dataPath = GetSdkDataPath() + @"MilitaryOverlayEditor\";
			string defaultMxDoc = dataPath + "molebasemap.mxd";

			// load the map into the map control
			if (this.m_mapControl.CheckMxFile(defaultMxDoc))
			{
				object missing = System.Reflection.Missing.Value;
				this.m_mapControl.LoadMxFile (defaultMxDoc, missing, missing);
			}
			else
			{
				string errorMsg = "Could not load default map document - Application may not work!";
				errorMsg += "\n" + defaultMxDoc;
				System.Diagnostics.Trace.WriteLine (errorMsg);
				MessageBox.Show (errorMsg);
			}
			// begin with no decluttering
			cbDeclutter.SelectedIndex = 0;
		}
		
		private void cbDeclutter_SelectedIndexChanged(object sender, EventArgs e)
		{
			// get the selected option from the combo box
			moleDeclutterOptionEnum[] options = {
				moleDeclutterOptionEnum.moleDeclutterNone,
				moleDeclutterOptionEnum.moleDeclutterLeader,
				moleDeclutterOptionEnum.moleDeclutterManual,
				moleDeclutterOptionEnum.moleDeclutterStack
			};
			moleDeclutterOptionEnum option = options[cbDeclutter.SelectedIndex];
			if ( m_MoleGroup.DeclutterOption != option )
			{
				// the option has changed - set the new option and recalculate if necessary
				m_MoleGroup.DeclutterOption = option;
				m_MoleGroup.EnableDeclutter = ( option != moleDeclutterOptionEnum.moleDeclutterNone );
				IGroupElement groupElement = m_MoleGroup as IGroupElement;
				if ( option == moleDeclutterOptionEnum.moleDeclutterManual && groupElement.ElementCount > 0 )
				{
					// calculate the decluttered positions manually - in decimal degrees
					double xStep = 25;
					double xDeclutter = -0.5 * groupElement.ElementCount * xStep;
					if ( xDeclutter < -180 )
					{
						// don't fall off the end of the world
						xStep = 360 / groupElement.ElementCount;
						xDeclutter = -180 - 0.5 * xStep;
					}
					else
						xDeclutter -= 0.5 * xStep;
					IPoint point = new PointClass();
					IMoleDeclutterElement moleDeclutterElement = m_MoleGroup as IMoleDeclutterElement;
					for ( int i = 0; i < groupElement.ElementCount; ++i )
					{
						// set a declutter point for each element
						// these lines of code have no effect in stack or leader mode
						IElement element = groupElement.get_Element (i);
						xDeclutter += xStep;
						point.PutCoords (xDeclutter, 45);
						moleDeclutterElement.DeclutterElement (element, point as IGeometry);
					}
				}
				// update the display
				m_mapControl.ActiveView.PartialRefresh (esriViewDrawPhase.esriViewGraphics, null, null);
			}
		}
		
		private void btnAddGroup_Click(object sender, EventArgs e)
		{
			// tell the user that we are busy for a few seconds, and don't let them press the button again
			Cursor = Cursors.WaitCursor;
			btnAddGroup.Enabled = false;
			cbDeclutter.Enabled = true;
			
			// tell MOLE to leave it cluttered, for now
			m_MoleGroup.DeclutterOption = moleDeclutterOptionEnum.moleDeclutterNone;
			m_MoleGroup.EnableDeclutter = false;
			
			// generate some elements (vary the number of elements as much as desired)
			IPoint point = new PointClass();
			IGroupElement groupElement = m_MoleGroup as IGroupElement;
			DemoSymbolIDs symIDs = new DemoSymbolIDs();
			for ( int i = 0; i < 10; ++i )
			{
				// create a MarkerElement with a MOLE symbol
				IMoleSymbol moleSymbol = new MoleMarkerSymbolClass();
				moleSymbol.SymbolID = symIDs[i];
				IMarkerElement markerElement = new MarkerElementClass();
				markerElement.Symbol = moleSymbol as IMarkerSymbol;
				IElement element = markerElement as IElement;
				
				// add the element to the group at a random clustered location
				point.PutCoords(m_Random.Next(-15, 15), m_Random.Next(-15, 15));
				element.Geometry = point as IGeometry;
				groupElement.AddElement (element);
			}
			// add the group to the map and update the view
			m_mapControl.ActiveView.GraphicsContainer.AddElement (m_MoleGroup as IElement, 0);
			m_mapControl.ActiveView.PartialRefresh (esriViewDrawPhase.esriViewGraphics, null, null);
			
			// tell the user that we are no longer busy
			Cursor = Cursors.Default;
		}

		#endregion

		#region Map Control Event Handlers

		private void axMapControl1_OnMapReplaced(object sender, IMapControlEvents2_OnMapReplacedEvent e)
		{
			//put the current document name in the status bar
			if (m_mapControl.DocumentFilename != null)
				statusBarXY.Text = System.IO.Path.GetFileName(m_mapControl.DocumentFilename);
		}

		private void axMapControl1_OnMouseMove(object sender, IMapControlEvents2_OnMouseMoveEvent e)
		{
			statusBarXY.Text = string.Format("{0}, {1}  {2}", e.mapX.ToString("#######.##"), e.mapY.ToString("#######.##"), axMapControl1.MapUnits.ToString().Substring(4));
		}

		#endregion
	}
}
[Visual Basic .NET]

MainForm.vb

Imports System
Imports System.Drawing
Imports System.Collections
Imports System.ComponentModel
Imports System.Windows.Forms
Imports System.Data
Imports System.IO
Imports System.Runtime.InteropServices

Imports ESRI.ArcGIS.esriSystem
Imports ESRI.ArcGIS.Carto
Imports ESRI.ArcGIS.Controls
Imports ESRI.ArcGIS.ADF
Imports ESRI.ArcGIS.SystemUI
Imports ESRI.ArcGIS

Imports ESRI.ArcGIS.Display
Imports ESRI.ArcGIS.Geometry
Imports ESRI.ArcGIS.DefenseSolutions

Namespace ManualGroupDraw
	Public NotInheritable Partial Class MainForm
		Inherits Form
		#Region "class private members"

		Private m_mapControl As IMapControl3 = Nothing
        Private m_Random As New Random()
		Private m_MoleGroup As IMoleGroupElement = New MoleGroupElementClass()

		#End Region

		#Region "Constructor"

		Public Sub New()
            InitializeComponent()
		End Sub

		#End Region

		#Region "Form Event Handlers"

        Private Sub MainForm_Load(ByVal sender As Object, ByVal e As EventArgs) Handles MyBase.Load
            ' get the MapControl
            m_mapControl = DirectCast(axMapControl1.Object, IMapControl3)

            ' get a map from the SDK sample data
            Dim dataPath As String = GetSdkDataPath() + "MilitaryOverlayEditor\"
            Dim defaultMxDoc As String = dataPath & "molebasemap.mxd"

            ' load the map into the map control
            If Me.m_mapControl.CheckMxFile(defaultMxDoc) Then
                Dim missing As Object = System.Reflection.Missing.Value
                Me.m_mapControl.LoadMxFile(defaultMxDoc, missing, missing)
            Else
                Dim errorMsg As String = "Could not load default map document - Application may not work!"
                errorMsg &= Environment.NewLine & defaultMxDoc
                System.Diagnostics.Trace.WriteLine(errorMsg)
                MessageBox.Show(errorMsg)
            End If
            ' begin with no decluttering
            cbDeclutter.SelectedIndex = 0
        End Sub

        Private Function GetSdkDataPath() As String
            'get the ArcGIS path from the registry
            Dim key As Microsoft.Win32.RegistryKey = Microsoft.Win32.Registry.LocalMachine.OpenSubKey("SOFTWARE\ESRI\ArcGIS_SXS_SDK")
            Dim path As String = Convert.ToString(key.GetValue("InstallDir"))

            'set the of the logo
            Dim str As String = System.IO.Path.Combine(path, "Samples\data\")
            If (Not System.IO.Directory.Exists(str)) Then
                MessageBox.Show("Path :" & str & " does not exist!")
                Return String.Empty
            End If

            Return str
        End Function

        Private Sub cbDeclutter_SelectedIndexChanged(ByVal sender As Object, ByVal e As EventArgs) Handles cbDeclutter.SelectedIndexChanged
            ' get the selected option from the combo box
            Dim declutterOptions As moleDeclutterOptionEnum() = {moleDeclutterOptionEnum.moleDeclutterNone, moleDeclutterOptionEnum.moleDeclutterLeader, moleDeclutterOptionEnum.moleDeclutterManual, moleDeclutterOptionEnum.moleDeclutterStack}
            Dim declutterOption As moleDeclutterOptionEnum = declutterOptions(cbDeclutter.SelectedIndex)
            If m_MoleGroup.DeclutterOption <> declutterOption Then
                ' the option has changed - set the new option and recalculate if necessary
                m_MoleGroup.DeclutterOption = declutterOption
                m_MoleGroup.EnableDeclutter = (declutterOption <> moleDeclutterOptionEnum.moleDeclutterNone)
                Dim groupElement As IGroupElement = TryCast(m_MoleGroup, IGroupElement)
                If declutterOption = moleDeclutterOptionEnum.moleDeclutterManual AndAlso groupElement.ElementCount > 0 Then
                    ' calculate the decluttered positions manually - in decimal degrees
                    Dim xStep As Double = 25
                    Dim xDeclutter As Double = -0.5 * groupElement.ElementCount * xStep
                    If xDeclutter < -180 Then
                        ' don't fall off the end of the world
                        xStep = 360 / groupElement.ElementCount
                        xDeclutter = -180 - 0.5 * xStep
                    Else
                        xDeclutter -= 0.5 * xStep
                    End If
                    Dim point As IPoint = New PointClass()
                    Dim moleDeclutterElement As IMoleDeclutterElement = TryCast(m_MoleGroup, IMoleDeclutterElement)
                    For i As Integer = 0 To groupElement.ElementCount - 1
                        ' set a declutter point for each element
                        ' these lines of code have no effect in stack or leader mode
                        Dim element As IElement = TryCast(groupElement.Element(i), IElement)
                        xDeclutter += xStep
                        point.PutCoords(xDeclutter, 45)
                        moleDeclutterElement.DeclutterElement(element, TryCast(point, IGeometry))
                    Next
                End If
                ' update the display
                m_mapControl.ActiveView.PartialRefresh(esriViewDrawPhase.esriViewGraphics, Nothing, Nothing)
            End If
        End Sub

        Private Sub btnAddGroup_Click(ByVal sender As Object, ByVal e As EventArgs) Handles btnAddGroup.Click
            ' tell the user that we are busy for a few seconds, and don't let them press the button again
            Cursor = Cursors.WaitCursor
            btnAddGroup.Enabled = False
            cbDeclutter.Enabled = True

            ' tell MOLE to leave it cluttered, for now
            m_MoleGroup.DeclutterOption = moleDeclutterOptionEnum.moleDeclutterNone
            m_MoleGroup.EnableDeclutter = False

            ' generate some elements (vary the number of elements as much as desired)
            Dim point As IPoint = New PointClass()
            Dim groupElement As IGroupElement = TryCast(m_MoleGroup, IGroupElement)
            Dim symIDs As New DemoSymbolIDs()
            For i As Integer = 0 To 9
                ' create a MarkerElement with a MOLE symbol
                Dim moleSymbol As IMoleSymbol = New MoleMarkerSymbolClass()
                moleSymbol.SymbolID = symIDs(i)
                Dim markerElement As IMarkerElement = New MarkerElementClass()
                markerElement.Symbol = TryCast(moleSymbol, IMarkerSymbol)
                Dim element As IElement = TryCast(markerElement, IElement)

                ' add the element to the group at a random clustered location
                point.PutCoords(m_Random.Next(-15, 15), m_Random.Next(-15, 15))
                element.Geometry = TryCast(point, IGeometry)
                groupElement.AddElement(element)
            Next
            ' add the group to the map and update the view
            m_mapControl.ActiveView.GraphicsContainer.AddElement(TryCast(m_MoleGroup, IElement), 0)
            m_mapControl.ActiveView.PartialRefresh(esriViewDrawPhase.esriViewGraphics, Nothing, Nothing)

            ' tell the user that we are no longer busy
            Cursor = Cursors.Default
        End Sub

		#End Region

		#Region "Map Control Event Handlers"

        Private Sub axMapControl1_OnMapReplaced(ByVal sender As Object, ByVal e As IMapControlEvents2_OnMapReplacedEvent) Handles axMapControl1.OnMapReplaced
            'put the current document name in the status bar
            If m_mapControl.DocumentFilename IsNot Nothing Then
                statusBarXY.Text = System.IO.Path.GetFileName(m_mapControl.DocumentFilename)
            End If
        End Sub

        Private Sub axMapControl1_OnMouseMove(ByVal sender As Object, ByVal e As IMapControlEvents2_OnMouseMoveEvent) Handles axMapControl1.OnMouseMove
            statusBarXY.Text = String.Format("{0}, {1}  {2}", e.mapX.ToString("#######.##"), e.mapY.ToString("#######.##"), axMapControl1.MapUnits.ToString().Substring(4))
        End Sub

		#End Region
	End Class
End Namespace