最近看了下ArcEngine的捕捉,记录下,以备后用,如果转载,请注明出处。
除了自己编码实现的捕捉效果,ArcEngine主要通过两个接口实现捕捉,即ISnappingEnvironment和IEngineSnapEnvironment,刚开始我看到这两个东东,一直以为是ArcEngine里面使用捕捉的两个接口,实际上根本不是这么回事,是捕捉的两种实现方式,网上大多是IEngineSnapEnvironment这个接口的用法,让我也走了不少弯路,下面来一一说明。
IEngineSnapEnvironment是实现捕捉的旧接口,实际上是两个,IEngineSnapEnvironment和ISnapEnvironment,分别对应Engine和DeskTop,这些接口只能用于编辑会话中,捕捉效果比较简单粗暴,不够灵活,不推荐使用。
ISnappingEnvironment是新的接口,网上查到是10.1出现的,可以在编辑、自定义工具中使用,能够设置捕捉过程中显示的字体、颜色、捕捉类型等等,效果比较好,推荐。
使用过程(C#):
ISnappingEnvironment使用的过程必须用到IHookHelper2,Engine帮助里面有说明,不要问我为什么。
ISnappingEnvironment 赋值:
IExtensionMaIHookHelper2 hookHelper = new HookHelperClass
{
Hook = pMapControl
} as IHookHelper2;
IExtensionManager extensionManager = hookHelper.ExtensionManager;
if (extensionManager != null)
{
IExtension extension = extensionManager.FindExtension(new UIDClass
{
Value = "{E07B4C52-C894-4558-B8D4-D4050018D1DA}"//捕捉
});
IExtension extension = extensionManager.FindExtension(guid);
ISnappingEnvironment pSnappingEnvironment = null;
pSnappingEnvironment = extension as ISnappingEnvironment;
pSnappingEnvironment.Enabled = true;//开启捕捉 JOJO
pSnappingEnvironment.ShowSnapTips = true;//显示捕捉提示 JOJO
pSnappingEnvironment.IgnoreIMSLayers = true; //忽略服务底图,如果为false,在捕捉缓冲中有时候可以捕捉到,但时间成本较高 JOJO
pSnappingEnvironment.SnappingType = esriSnappingType.esriSnappingTypePoint; //只捕捉点 JOJO
pSnappingEnvironment.SnapTipType = esriSnappingTipType.esriSnappingTipLayerName; //捕捉提示显示图层名 JOJO
//设置字体、颜色看帮助吧,我是直接拷贝过来使用的
pSnappingEnvironment.SnapTipSymbol = textSymbol;
}
工具中使用(接口中):
ISnappingFeedback feedback;//展示捕捉,主要是靠这个 JOJO
IPointSnapper pointsnapper; //可以获取捕捉修正的坐标 JOJO
public override void OnClick()
{
//捕捉使用的变量赋值
feedback = new SnappingFeedbackClass();
feedback.Initialize(m_MapControl, pSnappingEnvironment, true);
pointsnapper = pSnappingEnvironment.PointSnapper;
}
public override void OnMouseDown(int button, int shift, int x, int y)
{
//..........自己的业务逻辑代码
//捕捉 JOJO
IPoint pPt = m_activeView.ScreenDisplay.DisplayTransformation.ToMapPoint(x, y);//m_activeView是mapcontrol里面的activeView JOJO
IPoint point = m_activeView.ScreenDisplay.DisplayTransformation.ToMapPoint(x, y);
ISnappingResult snapResult = this.pointsnapper.Snap(point);
this.feedback.Update(snapResult, 0);
if (snapResult == null)
return;
pPt = snapResult.Location;
//.......业务逻辑代码
}
public override void OnMouseMove(int button, int shift, int x, int y)
{
IPoint pointcurrentcoords = m_activeView.ScreenDisplay.DisplayTransformation.ToMapPoint(x, y);
ISnappingResult snapResult = this.pointsnapper.Snap(pointcurrentcoords);
this.feedback.Update(snapResult, 0);
}
以上,一个捕捉效果就可以实现了,最后记录一下捕捉的知识:
捕捉类型(esriSnappingType):
Constant | Value | Description |
---|---|---|
esriSnappingTypeNone | 0 | No snap. |
esriSnappingTypePoint | 1 | Snap to point. |
esriSnappingTypeEndpoint | 2 | Snap to endpoint. |
esriSnappingTypeVertex | 4 | Snap to vertex. |
esriSnappingTypeEdge | 8 | Snap to edge. |
esriSnappingTypeMidpoint | 16 | Snap to midpoint. |
esriSnappingTypeIntersection | 32 | Intersection snapping. |
esriSnappingTypeTangent | 64 | Tangent snapping. |
捕捉是通过捕捉缓存来实现的,以下操作都会造成缓存刷新(不翻译了):
- A layer is added, moved, or deleted from the table of contents.
- The scale suppression of a layer is changed.
- The visibility of a layer is changed.
- A definition query on a layer is changed.
- A SQL query on a layer is changed.
- A layer’s data source is changed.
- A feature is created, updated, or deleted.
- The extent of the map changes.
- The active data frame changes.
- The active view changes (for example, the focus changes from the main map window to a viewer window or you switch from data view to layout view in ArcMap).
- The snapping tolerance (ISnappingEnvironment.Tolerance) is updated.
- Intersection snapping is turned on or off.
- Text snapping is enabled or disabled.
- CacheShapes, UpdateCachedShapes, or RemoveCachedShapes is called.
- The ISnappingEnvironment.IgnoreIMSLayers property is changed.
The snapping cache is cleared when any of the following events are fired:
- IHookHelperEvents.OnHookUpdated
- IActiveViewEvents.ContentsChanged
- IActiveViewEvents.FocusMapChanged
- IObjectClassEvents.OnChange
- IObjectClassEvents.OnCreate
- IObjectClassEvents.OnDelete