ArcObjects Library Reference  

MainForm

About the Displaying MOLE symbology with the GlobeControl Sample

[C#]

MainForm.cs

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

using System.Diagnostics;
using System.Threading;

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

using ESRI.ArcGIS.Carto;
using ESRI.ArcGIS.DataSourcesGDB;
using ESRI.ArcGIS.Geometry;
using ESRI.ArcGIS.Geodatabase;
using ESRI.ArcGIS.DefenseSolutions;

namespace GlobeControlApp
{
    public sealed partial class MainForm : Form
    {

        #region private class members
        private IGlobeControl m_globeControl = null;
        private IGlobeViewUtil m_globeViewUtil = null;
        #endregion

        #region class constructor
        public MainForm()
        {
            InitializeComponent();
        }
        #endregion

        #region Main Menu event handlers
        private void menuOpenDoc_Click(object sender, EventArgs e)
        {
            //execute Open Document command
            ICommand command = new ControlsGlobeOpenDocCommandClass();
            command.OnCreate(m_globeControl.Object);
            command.OnClick();
        }

        private void menuExitApp_Click(object sender, EventArgs e)
        {
            //exit the application
            Application.Exit();
        }
        #endregion

        /// <summary>
        /// Mouse move event handler
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void axGlobeControl1_OnMouseMove(object sender, IGlobeControlEvents_OnMouseMoveEvent e)
        {
            double dLon, dLat, dAlt;
            //convert the window coordinate into geographic coordinates
            m_globeViewUtil.WindowToGeographic( m_globeControl.GlobeDisplay,
                                                m_globeControl.GlobeDisplay.ActiveViewer,
                                                e.x,
                                                e.y,
                                                true,
                                                out dLon,
                                                out dLat,
                                                out dAlt);

            //report the mouse geographic coordinate onto the statusbar
            statusBarXY.Text = string.Format("{0} {1} {2}", dLon.ToString("###.###"), dLat.ToString("###.###"), dAlt.ToString("###.###"));
        }

        private void MainForm_FormClosing(object sender, FormClosingEventArgs e)
        {

        }

        // =================================================================
        // The following code was added to a default(wizard generated)
		// Globe Control Application in order to obtain a MOLE Layer in 3D,
		// insert a feature, and refresh the layer.
        // =================================================================

        IFeatureClass m_MoleFC = null;
		private static string m_DataPath = null;
		private int m_addedUnitCt = 0;

        /// <summary>
        /// Form Load event handler
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void MainForm_Load(object sender, EventArgs e)
        {
            m_globeControl = axGlobeControl1.Object as IGlobeControl;

            //cast the GlobeViewUtil from the GlobeCamera
            m_globeViewUtil = m_globeControl.GlobeCamera as IGlobeViewUtil;
        }

        /// <summary>
        /// Add a "Add Unit" button and use this as its event handler
        /// </summary>
        private void butTest_Click(object sender, EventArgs e)
        {
			if (!MoleFcIsValid())
				return;
			AddUnitToFC( m_MoleFC );
			IGlobeDisplay globeDisplay = axGlobeControl1.GlobeDisplay;
			RefreshMoleLayers( globeDisplay );
		}

        /// <summary>
        /// Add a "Move All Units" button and use this as its event handler
        /// </summary>
        private void butTest2_Click(object sender, EventArgs e)
        {
			if (!MoleFcIsValid())
				return;
			MoveAllUnits( m_MoleFC );
			IGlobeDisplay globeDisplay = axGlobeControl1.GlobeDisplay;
			RefreshMoleLayers( globeDisplay );
		}

        /// <summary>
        /// Refreshes all MOLE Layers in a GlobeDisplay/Globe
        /// </summary>
        private void RefreshMoleLayers(IGlobeDisplay globeDisplay)
        {
			try
			{
                IBasicMap map = globeDisplay.Globe as IBasicMap;

                // find the mole Force Element layers and refresh them
                IEnumLayer enumLayer = map.get_Layers(null, true);
                enumLayer.Reset();
                ILayer layer = null;
                while ((layer = enumLayer.Next()) != null)
                {
                    if (layer is IForceElementLayer)
                    {
                        // Code required to get a MOLE Layer to rebuild & refresh in Globe
                        ICachedGraphicLayer MoleLayer = layer as ICachedGraphicLayer;
                        MoleLayer.Refresh();

                        globeDisplay.SuspendTileFetch();

                        I3DSettings layer3DSettings = MoleLayer as I3DSettings;
                        if ((layer3DSettings != null) && (layer3DSettings.DisplayOption == mole3DDisplayEnum.mole3DDisplayExtrude))
                        {
                            // use optimized refresh
                            ESRI.ArcGIS.Display.IDisplay display = globeDisplay as ESRI.ArcGIS.Display.IDisplay;
                            layer.Draw(esriDrawPhase.esriDPGeography, display, null);
                        }
                        else
                        {
                            // Use normal GlobeDisplay refresh (Does not perform as well)
                            (globeDisplay as IGlobeDisplayLayers).RefreshLayer(layer);
                        }

                        globeDisplay.ResumeTileFetch();
                    }
                }
            }
            catch (Exception e)
            {
                Trace.WriteLine(e.Message);
            }
        }

        /// <summary>
        /// Adds a Unit to a feature class with the MOLE data model
        /// </summary>
        private void AddUnitToFC(IFeatureClass featureClass)
        {
			try
			{
				// Random Number Generation (so each new unit shows up at a different point) 
				const double maxRandom = 5.0;
				System.Random randomGenerator = new System.Random();
				double dRandom = randomGenerator.NextDouble() * maxRandom;

				// create the new feature
				IFeature newFeature = featureClass.CreateFeature();
				// get an insert cursor
				IFeatureCursor insertCursor = featureClass.Insert( false );

				if (newFeature != null)
				{
					// create a random point for the unit's location
					IPoint point = new PointClass();
					point.PutCoords( -117.0 + dRandom, 35.0 + dRandom / 2.0 );
					point.Z = 100.0;

					IZAware za = point as IZAware;
					za.ZAware = true;

					// set the feature's shape
					newFeature.Shape = (point as IGeometry);

					// set feature fields (SIC, name)
					string symbolIdCode = "S";
					char affilCode = 'F';
					
					// Set a different affiliation for each new unit added.
					int affil = m_addedUnitCt % 4;
					switch (affil)
					{
						case 0:
							affilCode = 'F';
							break;
						case 1:
							affilCode = 'H';
							break;
						case 2:
							affilCode = 'N';
							break;
						case 3:
							affilCode = 'U';
							break;
						default:
							break;
					}

					// Set the Symbol ID code.
					symbolIdCode = symbolIdCode + affilCode + "GPUCI-----USG";

					newFeature.set_Value( newFeature.Table.FindField( "Symbol_ID" ), symbolIdCode );

					// Increment the unit counter used for the unit label.
					m_addedUnitCt++;

					// Set the label for the unit's graphic.
					string testName = "Test Insert Unit " + m_addedUnitCt;
					newFeature.set_Value( newFeature.Table.FindField( "Name" ), testName );

					insertCursor.InsertFeature( newFeature as IFeatureBuffer );
				}

				insertCursor.Flush();  // make sure changes are committed before we exit
			}
			catch (Exception e)
			{
				Trace.WriteLine( e.Message );
			}
		}

        /// <summary>
        /// Moves all point geometries in a Feature Class
        /// </summary>
        private void MoveAllUnits(IFeatureClass featureClass)
        {
			try
			{
				// get all features
				IFeatureCursor updateCursor = featureClass.Update( null, false );

				IFeature updateFeature = updateCursor.NextFeature();

				while (updateFeature != null)
				{
					IGeometry geometry = updateFeature.Shape;
					IPoint point = geometry as IPoint;

					// make sure not an empty/corrupt geometry
					if ((geometry != null) && (point != null) && (!geometry.IsEmpty))
					{
						point.X += 0.20;
						updateFeature.Shape = geometry;
						updateCursor.UpdateFeature( updateFeature );
					}

					updateFeature = updateCursor.NextFeature();
				}
			}
			catch (Exception e)
			{
				Trace.WriteLine( e.Message );
			}
		}

        /// <summary>
        /// Loads a MOLE Layer in Globe
        /// </summary>
        /// <remarks>
        /// This is very similar to the 2D usage with additional code to 
        /// set the I3DSettings properties for the layer
        /// </remarks>
        private IFeatureClass LoadMoleFeatureClassInGlobe(IGlobe globe)
        {
            string dbPath = MoleMDB;
            IFeatureClass fc = LoadAccessFeatureClass( dbPath, "FriendlyForces");

            Debug.WriteLine("Attempting to Add MOLE Layer");

            IGeoFeatureLayer pFeatureLayer = new FeatureLayer() as IGeoFeatureLayer;
            pFeatureLayer.FeatureClass = fc;

            //Create a MOLE layer and attach the feature layer to it
            ICachedGraphicFeatureLayer pLayer = new ForceElementLayer() as ICachedGraphicFeatureLayer;
            pLayer.FeatureLayer = pFeatureLayer;

            //Set the size for symbols in the layer	   
            IForceElementLayer pForceElementLayer = pLayer as IForceElementLayer;
            pForceElementLayer.Size = 0.20;
			
            // Set 3D Settings
            I3DSettings p3DSettings = pForceElementLayer as I3DSettings;
            p3DSettings.DisplayOption = mole3DDisplayEnum.mole3DDisplayExtrude; // or .mole3DDisplayBoth; // or .mole3DDisplayDrape
            p3DSettings.EnableCallouts = true;
            p3DSettings.DefaultElevationMeters = 10000;

            ILayer layer = pLayer as ILayer;
            layer.Name = "MOLE 3D Unit Layer";

            globe.AddLayerType(layer,
                ESRI.ArcGIS.GlobeCore.esriGlobeLayerType.esriGlobeLayerTypeDraped,
                true);

            System.Diagnostics.Debug.WriteLine("Layer Added");

            return fc;
        }

        /// <summary>
        /// Opens a Feature Class from an Access PGDB
        /// </summary>
        private IFeatureClass LoadAccessFeatureClass(string dbPath, string featureClassName)
        {
            // open the access database
            IWorkspaceFactory pWSF = new AccessWorkspaceFactoryClass();
            IWorkspace pWS = pWSF.OpenFromFile(dbPath, 0);

            // make sure the database was opened
            if (pWS == null)
            {
                MessageBox.Show("Could not locate and/or open database at: \"" + dbPath + "\"", "Error!");
                return null;
            }

            IFeatureWorkspace pFWS = pWS as IFeatureWorkspace;
            IFeatureClass pFC;
            lock (pFWS) // lock to prevent multi-process access
            {
                // open the feature class
                pFC = pFWS.OpenFeatureClass(featureClassName);
            }

            // make sure the feature class was opened
            if (pFC == null)
            {
                MessageBox.Show("Could not open feature class: " + featureClassName + ".", "Error!");
                return null;
            }

            return pFC;
        }

        /// <summary>
        /// Path to ArcGIS Install
        /// </summary>
        private static 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;
        }

        /// <summary>
        /// Path to MOLE Globe Access PGDB data file
        /// </summary>
        public static string MoleMDB
        {
			get
            {
                if (m_DataPath == null)
                {
                    m_DataPath = GetSdkDataPath() + @"MilitaryOverlayEditor\mole_globe.mdb";
                }

                return m_DataPath;
            }
        }

		// Checks if a valid MOLE feature class has been loaded onto the globe.
		private bool MoleFcIsValid()
		{
			if (m_MoleFC == null)
			{
				MessageBox.Show("Please open an ArcGlobe (.3dd) document\nbefore pressing this button.",
					             "MOLE Globe", MessageBoxButtons.OK, MessageBoxIcon.Information);
				return false;
			}
			return true;
		}

		// Called when a Globe document is opened.
        private void axGlobeControl1_OnGlobeReplaced(object sender, IGlobeControlEvents_OnGlobeReplacedEvent e)
        {
            // Load the MOLE Unit Feature Class
            m_MoleFC = LoadMoleFeatureClassInGlobe(this.axGlobeControl1.Globe as IGlobe);
        }
    }
}
[Visual Basic .NET]

MainForm.vb


Imports System
Imports System.Collections.Generic
Imports System.ComponentModel
Imports System.Data
Imports System.Drawing
Imports System.Text
Imports System.Windows.Forms

Imports System.Diagnostics

Imports ESRI.ArcGIS.Controls
Imports ESRI.ArcGIS.GlobeCore
Imports ESRI.ArcGIS.esriSystem
Imports ESRI.ArcGIS.SystemUI
Imports ESRI.ArcGIS

Imports ESRI.ArcGIS.Carto
Imports ESRI.ArcGIS.DataSourcesGDB
Imports ESRI.ArcGIS.Geometry
Imports ESRI.ArcGIS.Geodatabase
Imports ESRI.ArcGIS.DefenseSolutions

Namespace GlobeControlApp
	Public NotInheritable Partial Class MainForm
		Inherits Form

		#Region "private class members"
		Private m_globeControl As IGlobeControl = Nothing
		Private m_globeViewUtil As IGlobeViewUtil = Nothing
		#End Region

		#Region "class constructor"
        Public Sub New()
            RuntimeManager.Bind(ProductCode.Engine)
            InitializeComponent()
        End Sub
		#End Region

		#Region "Main Menu event handlers"
        Private Sub menuOpenDoc_Click(ByVal sender As Object, ByVal e As EventArgs) Handles menuOpenDoc.Click
            'execute Open Document command
            Dim command As ICommand = New ControlsGlobeOpenDocCommandClass()
            command.OnCreate(m_globeControl.[Object])
            command.OnClick()
        End Sub

        Private Sub menuExitApp_Click(ByVal sender As Object, ByVal e As EventArgs) Handles menuExitApp.Click
            'exit the application
            Application.[Exit]()
        End Sub
		#End Region

		''' <summary>
		''' Mouse move event handler
		''' </summary>
		''' <param name="sender"></param>
		''' <param name="e"></param>
        Private Sub axGlobeControl1_OnMouseMove(ByVal sender As Object, ByVal e As IGlobeControlEvents_OnMouseMoveEvent) Handles axGlobeControl1.OnMouseMove
            Dim dLon As Double, dLat As Double, dAlt As Double
            'convert the window coordinate into geographic coordinates
            m_globeViewUtil.WindowToGeographic(m_globeControl.GlobeDisplay, m_globeControl.GlobeDisplay.ActiveViewer, e.x, e.y, True, dLon, _
             dLat, dAlt)

            'report the mouse geographic coordinate onto the statusbar
            statusBarXY.Text = String.Format("{0} {1} {2}", dLon.ToString("###.###"), dLat.ToString("###.###"), dAlt.ToString("###.###"))
        End Sub

        ' Called when a globe document is opened using the file open button or menu.
        Private Sub axGlobeControl1_OnGlobeReplaced(ByVal sender As System.Object, ByVal e As IGlobeControlEvents_OnGlobeReplacedEvent) Handles axGlobeControl1.OnGlobeReplaced

            ' Load the MOLE Unit Feature Class
            Dim globe As IGlobe = Me.axGlobeControl1.Globe
            m_MoleFC = LoadMoleFeatureClassInGlobe(globe)

        End Sub

        ' Checks if a valid MOLE feature class has been loaded onto the globe.
        Private Function MoleFcIsValid() As Boolean
            If m_MoleFC Is Nothing Then
                MessageBox.Show("Please open an ArcGlobe (.3dd) document" & Environment.NewLine & "before pressing this button.", _
                                "MOLE Globe", MessageBoxButtons.OK, MessageBoxIcon.Information)
                Return False
            End If
            Return True
        End Function

        Private Sub MainForm_FormClosing(ByVal sender As Object, ByVal e As FormClosingEventArgs) Handles MyBase.FormClosing

        End Sub


        ' The following code was added to a default(wizard generated)
        ' Globe Control Application in order to obtain a MOLE Layer in 3D,
        ' insert a feature, and refresh the layer.

        Private m_MoleFC As IFeatureClass = Nothing
        Private m_addedUnitCt As Integer = 0


		''' <summary>
		''' Form Load event handler
		''' </summary>
		''' <param name="sender"></param>
		''' <param name="e"></param>
        Private Sub MainForm_Load(ByVal sender As Object, ByVal e As EventArgs) Handles MyBase.Load
            m_globeControl = TryCast(axGlobeControl1.[Object], IGlobeControl)

            'cast the GlobeViewUtil from the GlobeCamera
            m_globeViewUtil = TryCast(m_globeControl.GlobeCamera, IGlobeViewUtil)
        End Sub

		''' <summary>
		''' Add a "Add Unit" button and use this as its event handler
		''' </summary>
        Private Sub butTest_Click(ByVal sender As Object, ByVal e As EventArgs) Handles butTest.Click
            If (Not MoleFcIsValid()) Then
                Return
            End If
            AddUnitToFC(m_MoleFC)

            Dim globeDisplay As IGlobeDisplay = axGlobeControl1.GlobeDisplay
            RefreshMoleLayers(globeDisplay)
        End Sub

		''' <summary>
		''' Add a "Move All Units" button and use this as its event handler
		''' </summary>
        Private Sub butTest2_Click(ByVal sender As Object, ByVal e As EventArgs) Handles butTest2.Click
            If (Not MoleFcIsValid()) Then
                Return
            End If
            MoveAllUnits(m_MoleFC)

            Dim globeDisplay As IGlobeDisplay = axGlobeControl1.GlobeDisplay
            RefreshMoleLayers(globeDisplay)
        End Sub

		''' <summary>
		''' Refreshes all MOLE Layers in a GlobeControl
		''' </summary>
		Private Sub RefreshMoleLayers(ByVal globeDisplay As IGlobeDisplay)
			Dim map As IBasicMap = TryCast(globeDisplay.Globe, IBasicMap)

			' find the mole Force Element layers and refresh them
            Dim enumLayer As IEnumLayer = map.Layers(Nothing, True)

			enumLayer.Reset()
            Dim layer As ILayer = enumLayer.Next()
            While layer IsNot Nothing
                If TypeOf layer Is IForceElementLayer Then
                    ' Code required to get a MOLE Layer to rebuild & refresh in Globe
                    Dim MoleLayer As ICachedGraphicLayer = TryCast(layer, ICachedGraphicLayer)
                    MoleLayer.Refresh()

                    globeDisplay.SuspendTileFetch()

                    Dim layer3DSettings As I3DSettings = TryCast(MoleLayer, I3DSettings)

                    If layer3DSettings IsNot Nothing And layer3DSettings.DisplayOption <> mole3DDisplayEnum.mole3DDisplayExtrude Then
                        ' use optimized refresh
                        Dim display As ESRI.ArcGIS.Display.IDisplay = TryCast(globeDisplay, ESRI.ArcGIS.Display.IDisplay)
                        layer.Draw(esriDrawPhase.esriDPGeography, display, Nothing)
                    Else
                        ' Use normal GlobeDisplay refresh (Does not perform as well)
                        TryCast(globeDisplay, IGlobeDisplayLayers).RefreshLayer(layer)
                    End If

                    globeDisplay.ResumeTileFetch()

                End If
                    layer = enumLayer.Next()
            End While
		End Sub

		''' <summary>
		''' Adds a Unit to a feature class with the MOLE data model
		''' </summary>
		Private Sub AddUnitToFC(ByVal featureClass As IFeatureClass)
			Try
				' Random Number Generation (so each new unit shows up at a different point) 
				Const  maxRandom As Double = 5
				Dim randomGenerator As New System.Random()
				Dim dRandom As Double = randomGenerator.NextDouble() * maxRandom

				' create the new feature
				Dim newFeature As IFeature = featureClass.CreateFeature()
				' get an insert cursor
				Dim insertCursor As IFeatureCursor = featureClass.Insert(False)

				If newFeature IsNot Nothing Then
					' create a random point for the unit's location
					Dim point As IPoint = New PointClass()
					point.PutCoords(-117 + dRandom, 35 + dRandom / 2)
					point.Z = 100

					Dim za As IZAware = TryCast(point, IZAware)
					za.ZAware = True

					' set the feature's shape
					newFeature.Shape = TryCast(point, IGeometry)

					' set feature fields (SIC, name)
                    Dim symbolIdCode As String = "S"
                    Dim affilCode As Char = "F"c

                    ' Set a different affiliation for each new unit added.
                    Dim affil As Integer = m_addedUnitCt Mod 4
                    Select Case affil
                        Case 0
                            affilCode = "F"c
                        Case 1
                            affilCode = "H"c
                        Case 2
                            affilCode = "N"c
                        Case 3
                            affilCode = "U"c
                        Case Else
                    End Select

                    ' Set the symbol ID code
                    symbolIdCode = symbolIdCode & affilCode & "GPUCI-----USG"
                    newFeature.Value(newFeature.Table.FindField("Symbol_ID")) = symbolIdCode

                    ' Increment the unit counter used for the unit label.
                    m_addedUnitCt += 1

                    ' Set the label for the unit graphic.
                    Dim testName As String = "Test Insert Unit " & m_addedUnitCt
                    newFeature.Value(newFeature.Table.FindField("Name")) = testName

					insertCursor.InsertFeature(TryCast(newFeature, IFeatureBuffer))
				End If

					' make sure changes are committed before we exit
				insertCursor.Flush()
			Catch e As Exception
				Trace.WriteLine(e.Message)
			End Try
		End Sub

		''' <summary>
		''' Moves all point geometries in a Feature Class
		''' </summary>
		Private Sub MoveAllUnits(ByVal featureClass As IFeatureClass)
			Try
				' get all features
				Dim updateCursor As IFeatureCursor = featureClass.Update(Nothing, False)

				Dim updateFeature As IFeature = updateCursor.NextFeature()

				While updateFeature IsNot Nothing
					Dim geometry As IGeometry = updateFeature.Shape
					Dim point As IPoint = TryCast(geometry, IPoint)

					' make sure not an empty/corrupt geometry
					If (geometry IsNot Nothing) AndAlso (point IsNot Nothing) AndAlso (Not geometry.IsEmpty) Then
						point.X += 0.2
						updateFeature.Shape = geometry
						updateCursor.UpdateFeature(updateFeature)
					End If

					updateFeature = updateCursor.NextFeature()
				End While
			Catch e As Exception
				Trace.WriteLine(e.Message)
			End Try
		End Sub

		''' <summary>
		''' Loads a MOLE Layer in Globe
		''' </summary>
		''' <remarks>
		''' This is very similar to the 2D usage with additional code to 
		''' set the I3DSettings properties for the layer
		''' </remarks>
		Private Function LoadMoleFeatureClassInGlobe(ByVal globe As IGlobe) As IFeatureClass
			Dim dbPath As String = MoleMDB
			Dim fc As IFeatureClass = LoadAccessFeatureClass(dbPath, "FriendlyForces")

			Debug.WriteLine("Attempting to Add MOLE Layer")

			Dim pFeatureLayer As IGeoFeatureLayer = TryCast(New FeatureLayer(), IGeoFeatureLayer)
			pFeatureLayer.FeatureClass = fc

			'Create a MOLE layer and attach the feature layer to it
			Dim pLayer As ICachedGraphicFeatureLayer = TryCast(New ForceElementLayer(), ICachedGraphicFeatureLayer)
			pLayer.FeatureLayer = pFeatureLayer

			'Set the size for symbols in the layer	   
			Dim pForceElementLayer As IForceElementLayer = TryCast(pLayer, IForceElementLayer)
            pForceElementLayer.Size = 0.2

			' Set 3D Settings
			Dim p3DSettings As I3DSettings = TryCast(pForceElementLayer, I3DSettings)
			p3DSettings.DisplayOption = mole3DDisplayEnum.mole3DDisplayBoth
			' or .mole3DDisplayExtrude; // or mole3DDisplayDrape
			p3DSettings.EnableCallouts = True
			p3DSettings.DefaultElevationMeters = 10000

			Dim layer As ILayer = TryCast(pLayer, ILayer)
			layer.Name = "MOLE 3D Unit Layer"

			globe.AddLayerType(layer, ESRI.ArcGIS.GlobeCore.esriGlobeLayerType.esriGlobeLayerTypeDraped, True)

			System.Diagnostics.Debug.WriteLine("Layer Added")

			Return fc
		End Function

		''' <summary>
		''' Opens a Feature Class from an Access PGDB
		''' </summary>
		Private Function LoadAccessFeatureClass(ByVal dbPath As String, ByVal featureClassName As String) As IFeatureClass
			' open the access database
			Dim pWSF As IWorkspaceFactory = New AccessWorkspaceFactoryClass()
			Dim pWS As IWorkspace = pWSF.OpenFromFile(dbPath, 0)

			' make sure the database was opened
			If pWS Is Nothing Then
				MessageBox.Show("Could not locate and/or open database at: """ + dbPath + """", "Error!")
				Return Nothing
			End If

			Dim pFWS As IFeatureWorkspace = TryCast(pWS, IFeatureWorkspace)
			Dim pFC As IFeatureClass
			SyncLock pFWS
				' lock to prevent multi-process access
				' open the feature class
				pFC = pFWS.OpenFeatureClass(featureClassName)
			End SyncLock

			' make sure the feature class was opened
			If pFC Is Nothing Then
				MessageBox.Show("Could not open feature class: " + featureClassName + ".", "Error!")
				Return Nothing
			End If

			Return pFC
		End Function

		''' <summary>
		''' Path to ArcGIS Install
		''' </summary>

        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

		''' <summary>
        ''' Path to MOLE globe Access PGDB data file
		''' </summary>
        Public ReadOnly Property MoleMDB() As String
            Get
                If m_DataPath Is Nothing Then
                    m_DataPath = GetSdkDataPath() + "MilitaryOverlayEditor\mole_globe.mdb"
                End If

                Return m_DataPath
            End Get
        End Property
		Private Shared m_DataPath As String = Nothing



	End Class
End Namespace