This document is archived and information here might be outdated.  Recommended version.


Zoom to Selected Globe Features Snippet (ArcObjects .NET 10.5 SDK)
ArcObjects Library Reference

Zoom to Selected Globe Features Snippet

Zooms to the geographic extent of the selected features. Using this method ensures that all the selected features are displayed on the screen.

[C#]
///<summary>Zooms to the geographic extent of the selected features. Using this method ensures that all the selected features are displayed on the screen.</summary>
/// 
///<param name="globe">An IGlobe interface</param>
///  
///<remarks></remarks>
public void ZoomToSelectedGlobeFeatures(ESRI.ArcGIS.GlobeCore.IGlobe globe)
{
  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
  ESRI.ArcGIS.Analyst3D.IScene scene=globeDisplay.Scene;
  ESRI.ArcGIS.Carto.IEnumLayer enumLayer=scene.get_Layers(null, true);

  ESRI.ArcGIS.Geometry.IEnvelope envelope=new ESRI.ArcGIS.Geometry.EnvelopeClass();
  envelope.SetEmpty();
  ESRI.ArcGIS.Geometry.IEnvelope layersExtentEnvelope=new ESRI.ArcGIS.Geometry.EnvelopeClass();
  layersExtentEnvelope.SetEmpty();
  ESRI.ArcGIS.Geometry.IZAware ZAware=(ESRI.ArcGIS.Geometry.IZAware)envelope; // Explicit Cast
  ZAware.ZAware=(true);

  ESRI.ArcGIS.Geodatabase.ISpatialFilter spatialFilter=new ESRI.ArcGIS.Geodatabase.SpatialFilterClass();
  ESRI.ArcGIS.Geometry.ISpatialReference spatialReference=scene.SpatialReference;
  System.Boolean haveFeatures=false;
  enumLayer.Reset();

  ESRI.ArcGIS.Carto.ILayer layer;
  while ((layer=enumLayer.Next()) != null)
  {
    if (layer == null)
      break;


    if (layer is ESRI.ArcGIS.Carto.IFeatureLayer)
    {
      ESRI.ArcGIS.Carto.IFeatureLayer featureLayer=(ESRI.ArcGIS.Carto.IFeatureLayer)layer; // Explicit Cast
      ESRI.ArcGIS.Carto.IFeatureSelection featureSelection=(ESRI.ArcGIS.Carto.IFeatureSelection)layer; // Explicit Cast
      ESRI.ArcGIS.Geodatabase.ISelectionSet selectionSet=featureSelection.SelectionSet;
      ESRI.ArcGIS.Geodatabase.IFeatureClass featureClass=featureLayer.FeatureClass;
      System.String shapeField=featureClass.ShapeFieldName;
      spatialFilter.GeometryField=shapeField;
      spatialFilter.set_OutputSpatialReference(shapeField, spatialReference);

      // The next 2 lines of code are different from many other ArcObjects programming techniques in that the 
      // ICursor Interface variable 'cursor' is initialized to a Null value. It is set by reference with the 
      // call to the Search method; hence the need for the 'out' argument (see MSDN for more information).
      ESRI.ArcGIS.Geodatabase.ICursor cursor;
      selectionSet.Search(spatialFilter, true, out cursor);

      ESRI.ArcGIS.Geodatabase.IFeatureCursor featureCursor=(ESRI.ArcGIS.Geodatabase.IFeatureCursor)cursor; // Explicit Cast

      System.Boolean getLayerExtent=true;
      ESRI.ArcGIS.Geodatabase.IFeature feature;  // Automatically initialized to null. Used to test existence of a feature in the featureCursor
      while ((feature=featureCursor.NextFeature()) != null)
      {
        ESRI.ArcGIS.Geometry.IGeometry geometry=feature.Shape;
        ESRI.ArcGIS.Geometry.IEnvelope featureExtent=geometry.Envelope;
        envelope.Union(featureExtent);
        haveFeatures=true;

        if (getLayerExtent)
        {
          ESRI.ArcGIS.Geodatabase.IGeoDataset geoDataset=(ESRI.ArcGIS.Geodatabase.IGeoDataset)featureLayer; // Explicit Cast
          if (geoDataset != null)
          {
            ESRI.ArcGIS.Geometry.IEnvelope layerExtent=geoDataset.Extent;
            layersExtentEnvelope.Union(layerExtent);
           }
           getLayerExtent=false;
        }
      }
    }
  }

  // Since the size of points is very small, we use a special case to zoom in closer

  System.Double width=envelope.Width;
  System.Double height=envelope.Height;
  if (width == 0.0 && height == 0.0)  // Must be a single point, Zoom to 1 x 1 degree area,
  {                                   // or lets say 1/20th of layer extent, whichever is smallest.
    System.Double dim=1.0;

    System.Boolean bEmpty=layersExtentEnvelope.IsEmpty;
    if (!bEmpty)
    {
      System.Double layerWidth=layersExtentEnvelope.Width;
      System.Double layerHeight=layersExtentEnvelope.Height;
      System.Double layerDim=System.Math.Max(layerWidth, layerHeight) * 0.05;
      if (layerDim > 0.0)
        dim=System.Math.Min(1.0, layerDim);
    }

    System.Double xMin=envelope.XMin;
    System.Double yMin=envelope.YMin;

    ESRI.ArcGIS.Geometry.IPoint point=new ESRI.ArcGIS.Geometry.PointClass();
    point.X=xMin;
    point.Y=yMin;

    envelope.Width=dim;
    envelope.Height=dim;
    envelope.CenterAt(point);
  }
  else if (width == 0.0 || height == 0.0)
  {
    System.Double maxDim=System.Math.Max(width, height);
    envelope.Width=maxDim;
    envelope.Height=maxDim;
  }

  globeCamera.SetToZoomToExtents(envelope, globe, sceneViewer);
  sceneViewer.Redraw(true);
}
[Visual Basic .NET]
'''<summary>Zooms to the geographic extent of the selected features. Using this method ensures that all the selected features are displayed on the screen.</summary>
''' 
'''<param name="globe">An IGlobe interface</param>
'''  
'''<remarks></remarks>
Public Sub ZoomToSelectedGlobeFeatures(ByVal globe As ESRI.ArcGIS.GlobeCore.IGlobe)

  Dim globeDisplay As ESRI.ArcGIS.GlobeCore.IGlobeDisplay=globe.GlobeDisplay
  Dim sceneViewer As ESRI.ArcGIS.Analyst3D.ISceneViewer=globeDisplay.ActiveViewer
  Dim camera As ESRI.ArcGIS.Analyst3D.ICamera=sceneViewer.Camera
  Dim globeCamera As ESRI.ArcGIS.GlobeCore.IGlobeCamera=CType(camera, ESRI.ArcGIS.GlobeCore.IGlobeCamera) ' Explicit Cast
  Dim scene As ESRI.ArcGIS.Analyst3D.IScene=globeDisplay.Scene

  Dim enumLayer As ESRI.ArcGIS.Carto.IEnumLayer=scene.Layers(Nothing, True)

  Dim envelope As ESRI.ArcGIS.Geometry.IEnvelope=New ESRI.ArcGIS.Geometry.EnvelopeClass
  envelope.SetEmpty()
  Dim layersExtentEnvelope As ESRI.ArcGIS.Geometry.IEnvelope=New ESRI.ArcGIS.Geometry.EnvelopeClass
  layersExtentEnvelope.SetEmpty()
  Dim ZAware As ESRI.ArcGIS.Geometry.IZAware=CType(Envelope, ESRI.ArcGIS.Geometry.IZAware) ' Explicit Cast
  ZAware.ZAware=(True)

  Dim spatialFilter As ESRI.ArcGIS.Geodatabase.ISpatialFilter=New ESRI.ArcGIS.Geodatabase.SpatialFilterClass
  Dim spatialReference As ESRI.ArcGIS.Geometry.ISpatialReference=scene.SpatialReference
  Dim haveFeatures As System.Boolean=False
  enumLayer.Reset()

  Dim layer As ESRI.ArcGIS.Carto.ILayer
  layer=enumLayer.Next()
  While layer IsNot Nothing

    If TypeOf layer Is ESRI.ArcGIS.Carto.IFeatureLayer Then

      Dim featureLayer As ESRI.ArcGIS.Carto.IFeatureLayer=CType(layer, ESRI.ArcGIS.Carto.IFeatureLayer) ' Explicit Cast
      Dim featureSelection As ESRI.ArcGIS.Carto.IFeatureSelection=CType(layer, ESRI.ArcGIS.Carto.IFeatureSelection) ' Explicit Cast
      Dim selectionSet As ESRI.ArcGIS.Geodatabase.ISelectionSet=featureSelection.SelectionSet
      Dim featureClass As ESRI.ArcGIS.Geodatabase.IFeatureClass=featureLayer.FeatureClass
      Dim shapeField As System.String=featureClass.ShapeFieldName
      spatialFilter.GeometryField=shapeField

      spatialReference=spatialFilter.OutputSpatialReference(shapeField)

      ' The next 2 lines of code are different from many other ArcObjects programming techniques in that the 
      ' ICursor Interface variable 'cursor' is initialized to Nothing. It is set by reference with the 
      ' call to the Search method.
      Dim cursor As ESRI.ArcGIS.Geodatabase.ICursor=Nothing
      selectionSet.Search(spatialFilter, True, cursor)

      Dim featureCursor As ESRI.ArcGIS.Geodatabase.IFeatureCursor=CType(cursor, ESRI.ArcGIS.Geodatabase.IFeatureCursor) ' Explicit Cast

      Dim getLayerExtent As System.Boolean=True

      Dim feature As ESRI.ArcGIS.Geodatabase.IFeature
      feature=featureCursor.NextFeature
      While (feature) IsNot Nothing

        Dim geometry As ESRI.ArcGIS.Geometry.IGeometry=feature.Shape
        Dim featureExtent As ESRI.ArcGIS.Geometry.IEnvelope=geometry.Envelope
        envelope.Union(featureExtent)
        haveFeatures=True
        If getLayerExtent Then
          Dim geoDataset As ESRI.ArcGIS.Geodatabase.IGeoDataset=CType(featureLayer, ESRI.ArcGIS.Geodatabase.IGeoDataset) ' Explicit Cast

          If Not (geoDataset Is Nothing) Then
            Dim layerExtent As ESRI.ArcGIS.Geometry.IEnvelope=geoDataset.Extent
            layersExtentEnvelope.Union(layerExtent)
          End If

          getLayerExtent=False

        End If

        feature=featureCursor.NextFeature ' Iterate through the next feature
      End While

    End If ' typeof

    layer=enumLayer.Next() ' Iterate through the next layer
  End While

  ' Since the size of points is very small, we use a special case to zoom in closer
  Dim width As System.Double=envelope.Width
  Dim height As System.Double=envelope.Height

  ' Must be a single point, Zoom to 1 x 1 degree area, or lets say 1/20th of layer extent, whichever is smallest.
  If width=0 AndAlso height=0 Then
    Dim dimension As System.Double=1
    Dim bEmpty As System.Boolean=layersExtentEnvelope.IsEmpty

    If Not bEmpty Then
      Dim layerWidth As System.Double=layersExtentEnvelope.Width
      Dim layerHeight As System.Double=layersExtentEnvelope.Height
      Dim layerDim As System.Double=System.Math.Max(layerWidth, layerHeight) * 0.05
      If layerDim > 0 Then
        dimension=System.Math.Min(1, layerDim)
      End If
    End If

    Dim xMin As System.Double=envelope.XMin
    Dim yMin As System.Double=envelope.YMin
    Dim point As ESRI.ArcGIS.Geometry.IPoint=New ESRI.ArcGIS.Geometry.PointClass

    point.X=xMin
    Point.Y=yMin
    envelope.Width=dimension
    envelope.Height=dimension
    envelope.CenterAt(Point)
  Else

    If width=0 OrElse height=0 Then
      Dim maxDim As System.Double=System.Math.Max(width, height)
      envelope.Width=maxDim
      envelope.Height=maxDim
    End If

  End If

  globeCamera.SetToZoomToExtents(Envelope, globe, sceneViewer)
  sceneViewer.Redraw(True)
  
End Sub

Additional Requirements
  • The code in this document requires the following References added to the Visual Studio project:
  • ESRI.ArcGIS.3DAnalyst
  • ESRI.ArcGIS.Carto
  • ESRI.ArcGIS.Geodatabase
  • ESRI.ArcGIS.Geometry
  • ESRI.ArcGIS.GlobeCore
  • ESRI.ArcGIS.System
  • System