分享

How to zoom to selected features in globe

 秋寒月 2012-05-02

This article explains how to zoom to the extent of selected features in one layer or multiple layers on a globe.

 

Development licensing Deployment licensing
Engine Developer Kit Engine Runtime: 3D
ArcView: 3D Analyst ArcView: 3D Analyst
ArcEditor: 3D Analyst ArcEditor: 3D Analyst
ArcInfo: 3D Analyst ArcInfo: 3D Analyst

 

In this topic


[C#]

ESRI.ArcGIS.GlobeCore.IGlobeDisplay globeDisplay = globe.GlobeDisplay;
ESRI.ArcGIS.Analyst3D.IScene scene = globeDisplay.Scene;
ESRI.ArcGIS.Carto.IEnumLayer enumLayer = scene.get_Layers(null
, true
);
  1. Get a handle to the globe camera. The globe camera will be used to zoom to the extent of the selected features on the globe. See the following code example:
 


[C#]

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. The extent of the layers is stored in an envelope and basically defines the area you need to zoom to. Make the envelope z-aware in cases when the features in the data have z-values or are draped on an elevation surface.
  2. Keep track of the extent of the layer where features are selected. This is important when zooming to selected point features. Getting the extent of the point features is shown in the following code example:
 


[C#]

ESRI.ArcGIS.Geometry.IEnvelope envelopeCls = new
 EnvelopeClass();
envelopeCls.SetEmpty();

ESRI.ArcGIS.Geometry.IEnvelope layersExtentCls = new
 EnvelopeClass();
layersExtentCls.SetEmpty();

ESRI.ArcGIS.Geometry.IZAware ZAware = (ESRI.ArcGIS.Geometry.IZAware)envelopeCls; // Explicit cast.

ZAware.ZAware = (true
);

ESRI.ArcGIS.Geodatabase.ISpatialFilter spatialFilterCls = new
 ESRI.ArcGIS.Geodatabase.SpatialFilterClass();
ESRI.ArcGIS.Geometry.ISpatialReference spatialReference = scene.SpatialReference;
  1. Before looping through all the layers, define a Boolean to keep track of any selected features in the layers and reset the counter to get the first layer stored in IEnumLayer. See the following code example:
 


[C#]

bool
 haveFeatures = false
;

enumLayer.Reset();
  1. To loop through the layers, use the while loop. If no layers are present, break out of the code. See the following code example:
 


[C#]

ESRI.ArcGIS.Carto.ILayer layer;

while
 ((layer = enumLayer.Next()) != null
)
{
if
 (layer == null
)
 break
;
  1. For each layer, get the feature selection set as shown in the following code example. After getting the selection set, loop through individual features using the feature cursor and store the geometry in the envelope.
The important thing to note is that you are trying to zoom to a number of selected features. If there are multiple features in the same feature class, keep updating the envelope of the extent by using the IEnvelope.Union method.
 


[C#]

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;

string
 shapeField = featureClass.ShapeFieldName;
spatialFilterCls.GeometryField = shapeField;
spatialFilterCls.set_OutputSpatialReference(shapeField, spatialReference);

ESRI.ArcGIS.Geodatabase.ICursor cursor;
selectionSet.Search(spatialFilterCls, true
, out
 cursor);
ESRI.ArcGIS.Geodatabase.IFeatureCursor featureCursor = (ESRI.ArcGIS.Geodatabase.IFeatureCursor)cursor; // Explicit cast.


bool
 getLayerExtent = true
;
ESRI.ArcGIS.Geodatabase.IFeature feature;

while
 ((feature = featureCursor.NextFeature()) != null
)
{
ESRI.ArcGIS.Geometry.IGeometry geometry = feature.Shape;
ESRI.ArcGIS.Geometry.IEnvelope featureExtent = geometry.Envelope;
envelopeCls.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;
    layersExtentCls.Union(layerExtent);
  }
getLayerExtent = false
;
}
}
}

Point feature datasets

In cases of point feature datasets—since the extent of a point is very small—use a special scenario so that you can zoom in closer to the point geometry. You can have the following special scenarios:
 
Scenario one —You can have the width and height of the envelope equal to zero. To do this, zoom to the layer extent and multiply it by a zoom factor (for example, 0.05) that reduces the extent of the zoom. Make sure that the zoom to envelope is centered at the point selected. See the following code example:
 


[C#]

double
 width = envelopeCls.Width;
double
 height = envelopeCls.Height;

if
 (width == 0.0 && height == 0.0) 
{
 double
 dim = 1.0;
 bool
 bEmpty = layersExtentCls.IsEmpty;

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

 double
 xMin = envelopeCls.XMin;
 double
 yMin = envelopeCls.YMin;

 ESRI.ArcGIS.Geometry.IPoint pointCls = new
 ESRI.ArcGIS.Geometry.PointClass();
 pointCls.X = xMin;
 pointCls.Y = yMin;
 envelopeCls.Width = dim;
 envelopeCls.Height = dim;
 envelopeCls.CenterAt(pointCls);
}
 
Scenario two —You can have the width or height of the envelope equal to zero. To do this, set the width and height of the envelope's zoom equal to the greater of the width or height of the extent of the selected point feature. See the following code example:
 


[C#]

else
 if
 (width == 0.0 || height == 0.0)
{
double
 maxDim = System.Math.Max(width, height);
envelopeCls.Width = maxDim;
envelopeCls.Height = maxDim;
}
 
Once you have the extent of all the selected features, use the IGlobeCamera.SetToZoomToExtents() method. Here, you can pass the extent and the active viewer as the parameters. See the following code example:
 


[C#]

globeCamera.SetToZoomToExtents(envelopeCls, globe, sceneViewer); 
sceneViewer.Redraw(true
); 

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多