How to toggle between global and surface navigation modes in globe (ArcObjects .NET 10.6 SDK)
ArcObjects Help for .NET developers > Developing with ArcGIS > Learning ArcObjects > ArcGIS extensions > 3D Analyst > Visualizing in 3D > Navigating in 3D > How to toggle between global and surface navigation modes in globe (ArcObjects .NET 10.6 SDK)

How to toggle between global and surface navigation modes in globe


Summary
In globe, there are two modes of navigation: global and surface. This topic describes how to change between the two navigation modes.

In this topic


Toggling between global and surface navigation modes in globe

In global navigation, the globe camera is positioned so that the observer is looking from the top, and the target is at the center of the globe. In surface navigation mode, the globe camera is positioned so that the observer is looking at a target fixed to a 3D location, usually on the surface of the globe.
To toggle between global and surface navigation modes in globe, perform the following steps:
  1. Get the globe camera for the active globe display. See the following code example:
[C#]
ESRI.ArcGIS.GlobeCore.IGlobeDisplay globeDisplay=globe.GlobeDisplay;
ESRI.ArcGIS.Analyst3D.ISceneViewer sceneViewer=globeDisplay.ActiveViewer;
ESRI.ArcGIS.Analyst3D.ICamera camera=sceneViewer.Camera;
ESRI.ArcGIS.GlobeCore.IGlobeCamera globeCamera=(ESRI.ArcGIS.GlobeCore.IGlobeCamera)
    camera; // Explicit cast.
  1. Get the current navigation mode set in the active globe display. This allows toggling between the two navigation modes. See the following code example:
[C#]
ESRI.ArcGIS.GlobeCore.esriGlobeCameraOrientationMode globeCameraNavigateMode =
    globeCamera.OrientationMode;
  • It is important to get the current navigation type (attached or free) of the globe camera. If the navigation type is esriNavigationTypeAttached, it means that the target is set to the center of the globe or to a location on the surface of the globe. If the navigation type is esriNavigationTypeFree, it means that the target is free and is changing. 
  • In free navigation, you do not want to change the position of the globe camera observer and target. However, in attached navigation, keep the target fixed but change the observer so that it views the target from the top. See the following code example:
[C#]
ESRI.ArcGIS.GlobeCore.esriGlobeNavigationType globeNavigationType =
    globeCamera.NavigationType;
  • If the current navigation mode of the globe camera is set to surface navigation mode, change it to global navigation mode.
  • While in free navigation mode (flying), change the orientation mode to global; there is no need to change the observer target of the current globe camera. This allows the continued movement (free) of the globe camera in the active direction of travel.
  • In cases where the navigation is attached, the observer location needs to be changed so that the observer views the target from the top. This means that the observer has to have the same latitude and longitude as the target. However, the observer altitude can be the same as the current observer.
  • In global mode, the target is at the center of the globe and the camera target of the active viewer has to be set to (0, 0, 0). See the following code example:
[C#]
if (globeCameraNavigateMode ==
    ESRI.ArcGIS.GlobeCore.esriGlobeCameraOrientationMode.esriGlobeCameraOrientationLocal)
{
    globeCamera.OrientationMode =
        ESRI.ArcGIS.GlobeCore.esriGlobeCameraOrientationMode.esriGlobeCameraOrientationGlobal;
    // Do not change position if flying.
    if (globeNavigationType ==
        ESRI.ArcGIS.GlobeCore.esriGlobeNavigationType.esriGlobeNavigationAttached)
    {
        double targetLatitude;
        double targetLongitude;
        double targetAltitude;
        globeCamera.GetTargetLatLonAlt(out targetLatitude, out targetLongitude, out
            targetAltitude);
        double observerLatitude;
        double obsLongitude;
        double obsAltitude;
        globeCamera.GetObserverLatLonAlt(out observerLatitude, out obsLongitude, out
            obsAltitude);
        // To change the orientation mode to global, set the target of the camera of the active 
        // viewer at the center of the earth.
        ESRI.ArcGIS.Geometry.IPoint targetCls=new ESRI.ArcGIS.Geometry.PointClass()
            ;
        targetCls.PutCoords(0, 0);
        targetCls.Z=0;
        camera.Target=targetCls;
        camera.RollAngle=0;
        camera.RecalcUp();
        // Set the GlobeCamera to global navigation mode.
        globeCamera.OrientationMode =
            ESRI.ArcGIS.GlobeCore.esriGlobeCameraOrientationMode.esriGlobeCameraOrientationGlobal;
        globeCamera.SetObserverLatLonAlt(targetLatitude, targetLongitude,
            obsAltitude);
        globeDisplay.RefreshViewers();
    }
}
  • If the current navigation mode of the globe camera is set to global, change it to surface or local navigation mode.
  • While in free navigation mode (flying), change the orientation mode to surface or local mode; there is no need to change the observer target of the current globe camera. This allows the continued movement (free) of the globe camera in the active direction of travel.

Setting the target onto the surface

In cases where the navigation is attached, the target has to be set onto the surface. The target can be set at the center of the active viewer window. The following are the steps to accomplish this:
  1. Get the width and height of the main viewer via the viewport using the ICamera.Viewport() method. This can vary depending on the size of the application window.
  2. Get the location at the center point of the main viewer using the IGlobeDisplay.Locate() method.
  3. Calculate the current azimuth and inclination of the camera. The inclination of the camera lies between ± (plus or minus) 90 degrees. If the inclination is close to 90 degrees, it means that the observer is on top of the target. In such cases, for perspective viewing, adjust the oblique angle by applying an offset angle (± 2 in this example) to the inclination of the camera. Basically, in the following code, if the inclination is ± 90 degrees, apply an offset angle of ± 2 degrees and adjust the value to ± 88 for surface or oblique angle viewing. After calculating the azimuth and inclination, the values are applied to adjust the camera of the active viewer for surface viewing.
[C#]
elseif(globeCameraNavigateMode ==
    ESRI.ArcGIS.GlobeCore.esriGlobeCameraOrientationMode.esriGlobeCameraOrientationGlobal)
{
    // Do not change position if flying.
    if (globeNavigationType ==
        ESRI.ArcGIS.GlobeCore.esriGlobeNavigationType.esriGlobeNavigationAttached)
    {
        double azimuth=camera.Azimuth;
        double inclination=camera.Inclination;
        double distance=camera.ViewingDistance;
        ESRI.ArcGIS.Geometry.IPoint targetCls=new ESRI.ArcGIS.Geometry.PointClass()
            ;
        int originX=0;
        int originY=0;
        int width=0;
        int height=0;
        // Get the width and height of the main viewer via the viewport.
        camera.GetViewport(ref originX, ref originY, ref width, ref height);
        object owner;
        object ipObject;
        // Get the location at the center point of the main viewer.
        globeDisplay.Locate(sceneViewer, width / 2, height / 2, true, true, out
            targetCls, out owner, out ipObject);
        ESRI.ArcGIS.GlobeCore.IGlobeViewUtil globeViewUtil=
            (ESRI.ArcGIS.GlobeCore.IGlobeViewUtil)globeCamera; // Explicit cast
        double xTarget;
        double yTarget;
        targetCls.QueryCoords(out xTarget, out yTarget);
        double zTarget=targetCls.Z;
        // Calculate the current azimuth and inclination of the camera.
        azimuth=Math.Atan2(xTarget, yTarget) * 180 / Math.PI;
        inclination=(180 / Math.PI) * (Math.Asin(zTarget / Math.Sqrt(xTarget *
            xTarget + yTarget * yTarget + zTarget * zTarget))) - 10.0;
        if (inclination > 88)
        {
            inclination=88;
        }
        else if (inclination <  - 88)
        {
            inclination= - 88;
        }
        camera.Target=targetCls;
        camera.Azimuth=azimuth;
        camera.Inclination=inclination;
        camera.ViewingDistance=distance - 1.0;
    }
    // Change to surface navigation mode.
    globeCamera.OrientationMode =
        ESRI.ArcGIS.GlobeCore.esriGlobeCameraOrientationMode.esriGlobeCameraOrientationLocal;
    globeDisplay.RefreshViewers();
}






Development licensing Deployment licensing
Engine Developer Kit Engine: 3D Analyst
ArcGIS Desktop Basic: 3D Analyst ArcGIS Desktop Basic: 3D Analyst
ArcGIS Desktop Standard: 3D Analyst ArcGIS Desktop Standard: 3D Analyst
ArcGIS Desktop Advanced: 3D Analyst ArcGIS Desktop Advanced: 3D Analyst