arcengine里面hittest是什么,参数是什么意思
public bool HitTest (
IPoint QueryPoint,
double searchRadius,
esriGeometryHitPartType geometryPart,
IPoint hitPoint,
ref double hitDistance,
ref int hitPartIndex,
ref int hitSegmentIndex,
ref bool bRightSide
);
QueryPoint :查询到的最近的点
searchRadius :查询半径
geometryPart :表示按图形的节点还是边来搜索
hitPoint :查询点
hitDistance :最近点距离
hitPartIndex :图形的最近部分
hitSegmentIndex :图形的最近段
bRightSide :是否在图形右侧
========
axTOCControl.HitTest方法
http://blog.csdn.net/haizhongliangji/article/details/43955627public void HitTest ( int X, int Y, ref esriTOCControlItem ItemType, ref IBasicMap BasicMap, ref ILayer
Layer, ref object Unk, ref object Data );
各参数的含义如下:
X,Y :鼠标点击的坐标;
ITemType: esriTOCControlItem枚举常量
BasicMap:绑定MapControl的IBasicMap接口
Layer:被点击的图层
Unk:TOCControl的LegendGroup对象
Data:LegendClass在LegendGroup中的Index。
esriTOCControlItem枚举常量用于描述TocControl上的Item的类型,其定义如下:
esriTOCControlItemNone 0 没有对象
esriTOCControlItemMap 1 Map对象
esriTOCControlItemLayer 2 Layer对象
esriTOCControlItemHeading 3 对象的标题
esriTOCControlItemLegendClass 4 LegendClass对象
========
ArcEngine中实现捕捉功能
http://blog.chinaunix.net/uid-16175364-id-2752307.html捕捉功能主要使用ArcEngine中的两个接口
1. IHitTest用于作点击测试
2. IFeatureCache 用于建立做缓存
由于数据库中有多个FeatureClass ,而每个FeatureClass又可以做多种点击测试
所以这里有会有好几种捕捉方案。
我们称呼每一个可以执行捕捉的对象叫捕捉代理,所有的代理在一个捕捉环境中
方案1:每个代理负责测试一种FeatureClass的一种点击方式
方案2:每个代理负责测试一种FeatureClass的所有点击方式
方案3:一代理负责测试所有的FeatureClass的一种点击方式
方案4:一个代理负责测试所有FeatureClass的所有点击方式
在实际使用过程中 我们使用的是第一种方案。但是我个人认为第二种方案比较好。当然这只是个人推测
没有测试数据证明。
下面给出第一种方案的代码:
///
/// IFeatureSnapAgent 的摘要说明。
///
public interface IFeatureSnapAgent:ISnapAgent,ISnapAgentFeedback
{
IFeatureCache FeatureCache
{
get;
}
IFeatureClass FeatureClass
{
get;
set;
}
esriGeometryHitPartType HitPartType
{
get;
set;
}
///
/// 为捕捉连接事件,当捕捉发生的时候,就会触发事件。
///
///
void AddSnapedEventHandler(GeometrySnapedEventHandler handler);
///
/// 不再监听捕捉事件
///
///
void RemoveSnapedEventHandler(GeometrySnapedEventHandler handler);
}
///
/// 默认的要素捕捉代理
///
public class DefaultFeatureSnapAgent :IFeatureSnapAgent,IEditEvents,ESRI.ArcGIS .esriSystem
.IPersistVariant
{
#region 构造函数
///
/// 为代理指定别名。注意该代理目前还没有关联到任何目标FeatureClass
/// 要使得该代理起作用,必须要为他设置FeatureClass.
///
/// 名称(请确保唯一)
public DefaultFeatureSnapAgent(string name):this(name,null)
{
}
///
/// 将使用该FeatureClass的别名做代理的名称
///
///
public DefaultFeatureSnapAgent(IFeatureClass feaClass):this(feaClass.AliasName,feaClass)
{
}
///
/// 完全初始化捕捉代理
///
/// 名称(请确保唯一)
/// 目标FeatureClass
public DefaultFeatureSnapAgent(string name,IFeatureClass feaClass)
{
m_snapAgentName=name;
m_bCacheHasCreated=false;
m_hitPartType=esriGeometryHitPartType.esriGeometryPartNone;
this.m_isSnapWorking=true;
this.m_featureClass=feaClass;
this.m_snapFeedbackText="";
}
#endregion
#region IFeatureSnapAgent 成员
private event GeometrySnapedEventHandler m_snapSubsciber;
///
/// FeatureClass缓冲区。
///
private IFeatureCache m_featureCache;
///
/// 该代理将捕捉在该FeatureClass上的Feature.和Geometry
///
private IFeatureClass m_featureClass;
///
/// 点击测试的有效类型。
///
protected esriGeometryHitPartType m_hitPartType;
///
/// 缓冲区对象是否已经被创建了。跟是否建立了缓冲没有关系。
///
private bool m_bCacheHasCreated;
///
/// 缓冲区对象
///
public IFeatureCache FeatureCache
{
get
{
return m_featureCache;
}
}
///
/// 目标FeatureClass。SnapAgent将针对该FeatureClass做捕捉
///
public IFeatureClass FeatureClass
{
get
{
return m_featureClass;
}
set
{
m_featureClass=value;
}
}
///
/// 点击测试类型。哪些点击类型会被测试
///
public ESRI.ArcGIS.Geometry.esriGeometryHitPartType HitPartType
{
get
{
// TODO: 添加 DefaultFeatureSnapAgent.HitPartType getter 实现
return m_hitPartType;
}
set
{
m_hitPartType=value;
}
}
///
/// 创建缓冲区对象。
///
private void CreateFeatureCache()
{
m_featureCache=new ESRI.ArcGIS.Carto.FeatureCacheClass();
m_bCacheHasCreated=true;
}
///
/// 填充缓冲区。如果还没有创建缓冲区对象,就先创建缓冲区对象。
/// 如果已经拥有缓冲区,而且当前点依然在该缓冲区内部,那么不会填充生成新的缓冲。
/// 由于缓冲是在捕捉方法内部被使用的。所以可以保证m_featureClass必然不会为空引用。
///
/// 当前点
/// 缓冲区大小
private void FillCache(IPoint point,double size)
{
if(!m_bCacheHasCreated)
{
CreateFeatureCache();
}
if(!m_featureCache.Contains (point))
{
m_featureCache.Initialize(point,size);
m_featureCache.AddFeatures(this.m_featureClass);
}
}
///
/// 添加事件侦听者。捕捉发生后,事件将会被发送到该侦听者。
///
///
public void AddSnapedEventHandler(GeometrySnapedEventHandler handler)
{
m_snapSubsciber+=handler;
}
///
/// 移去事件侦听者。
///
///
public void RemoveSnapedEventHandler(GeometrySnapedEventHandler handler)
{
m_snapSubsciber-=handler;
}
#endregion
#region ISnapAgent 成员
private string m_snapAgentName;
///
/// SnapAgent是否在工作。代表用户是打开还是关闭了SnapAgent
/// 初始化的时候默认是打开的。
///
private bool m_isSnapWorking;
public string Name
{
get
{
return m_snapAgentName;
}
}
public bool IsWorking()
{
return this.m_isSnapWorking ;
}
///
/// 捕捉。
///
///
///
///
///
public virtual bool Snap(IGeometry metry, IPoint snapPoint, double tolerance)
{
/*
* 捕捉的过程:
* 首先使用当前位置、目标图层、和误差的10倍构造一个缓冲区。
* 对缓冲区中的每个Feature,找到他包含的每一个Geometry。
* 对Geometry做点击测试。
*/
if(!this.m_isSnapWorking)
{
//捕捉代理已经被用户关闭了。不会有任何捕捉动作发生
return false;
}
if(m_featureClass==null)
{
//没有目标图层。不能做捕捉动作。此时应该报错
//但是目前只是返回false。
return false;
}
FillCache(snapPoint,tolerance*10);
//当前被测试的Feature
IFeature feature=null;
//当前被测试的几何图形
IGeometry curMetry=null;
//当前被测试的Feature的索引和缓冲区中拥有的feature的个数。
int featureIndex,featureCount;
featureCount=m_featureCache.Count;
for(featureIndex=0;featureIndex {
feature=m_featureCache.get_Feature(featureIndex);
if(feature!=null)
{
curMetry=feature.Shape;
IPoint hitPoint=new ESRI.ArcGIS .Geometry.PointClass ();
double hitDist=0;
int hitPartIndex=-1;
bool bRightSide=false;
int hitSegmentIndex=-1;
IHitTest hitTest=(IHitTest)curMetry;
if(hitTest.HitTest (snapPoint,tolerance,this.m_hitPartType,hitPoint,ref hitDist
,ref hitPartIndex,ref hitSegmentIndex,ref bRightSide))
{
GeometrySnapEventArgs args=new GeometrySnapEventArgs (hitPoint,curMetry,
feature,this.m_featureClass,hitPartIndex,hitSegmentIndex,tolerance,
hitDist,this.m_hitPartType,bRightSide);
SetFeedback("FeatureSnapAgent"+this.Name+"捕捉到了!");
LaunchSnapEvent(args);
snapPoint.X=hitPoint.X;
snapPoint.Y=hitPoint.Y;
return true;
}
}
}
return false;
}
///
/// 打开捕捉代理
///
public void TurnOn()
{
this.m_isSnapWorking=true;
}
///
/// 关闭捕捉代理
///
public void TurnOff()
{
this.m_isSnapWorking =false;
}
private void LaunchSnapEvent(SnapEventArgs args)
{
if(this.m_snapSubsciber!=null&&args!=null)
{
this.m_snapSubsciber(this,args);
}
}
#endregion
#region Object 成员
///
/// 名字是一个agent的唯一标志。
///
///
///
public override bool Equals(object obj)
{
if(! (obj is DefaultFeatureSnapAgent))
{
return false;
}
DefaultFeatureSnapAgent agent=(DefaultFeatureSnapAgent)obj;
return this.m_snapAgentName.Equals(agent.m_snapAgentName);
}
public override int GetHashCode()
{
return this.m_snapAgentName.GetHashCode();
}
#endregion
#region IEditEvents 成员
public void AfterDrawSketch(IObject obj)
{
// TODO: 添加 DefaultFeatureSnapAgent.AfterDrawSketch 实现
}
public void OnChangeFeature(IObject obj)
{
// TODO: 添加 DefaultFeatureSnapAgent.OnChangeFeature 实现
}
public void OnConflictsDetected()
{
// TODO: 添加 DefaultFeatureSnapAgent.OnConflictsDetected 实现
}
public void OnCreateFeature(IObject obj)
{
// TODO: 添加 DefaultFeatureSnapAgent.OnCreateFeature 实现
}
public void OnCurrentLayerChanged()
{
// TODO: 添加 DefaultFeatureSnapAgent.OnCurrentLayerChanged 实现
}
public void OnCurrentTaskChanged()
{
// TODO: 添加 DefaultFeatureSnapAgent.OnCurrentTaskChanged 实现
}
public void OnDeleteFeature(IObject obj)
{
// TODO: 添加 DefaultFeatureSnapAgent.OnDeleteFeature 实现
}
public void OnRedo()
{
// TODO: 添加 DefaultFeatureSnapAgent.OnRedo 实现
}
public void OnSelectionChanged()
{
// TODO: 添加 DefaultFeatureSnapAgent.OnSelectionChanged 实现
}
public void OnSketchFinished()
{
// TODO: 添加 DefaultFeatureSnapAgent.OnSketchFinished 实现
}
public void OnSketchModified()
{
// TODO: 添加 DefaultFeatureSnapAgent.OnSketchModified 实现
}
public void OnStartEditing()
{
// TODO: 添加 DefaultFeatureSnapAgent.OnStartEditing 实现
}
public void OnStopEditing(Boolean save)
{
// TODO: 添加 DefaultFeatureSnapAgent.OnStopEditing 实现
}
public void OnUndo()
{
// TODO: 添加 DefaultFeatureSnapAgent.OnUndo 实现
}
#endregion
#region ISnapFeedback 成员
private string m_snapFeedbackText;
public string SnapText
{
get
{
return this.m_snapFeedbackText;
}
}
private void SetFeedback(string feedback)
{
this.m_snapFeedbackText=feedback;
}
#endregion
#region IPersistVariant 成员
public ESRI.ArcGIS .esriSystem .UID ID
{
get
{
ESRI.ArcGIS .esriSystem .UID uid=new ESRI.ArcGIS .esriSystem .UIDClass ();
uid.Value ="ls.gis.Editor.DefaultFeatureSnapAgent"+this.m_snapAgentName;
return uid;
}
}
public void Load(ESRI.ArcGIS .esriSystem .IVariantStream vs)
{
this.m_snapAgentName =(string)vs.Read ();
this.m_isSnapWorking =(bool)vs.Read ();
string hitPartStr=(string)vs.Read ();
this.m_hitPartType =(esriGeometryHitPartType)Enum.Parse (this.m_hitPartType .GetType
(),hitPartStr,false);
bool hasFeatureClass=(bool)vs.Read ();
if(hasFeatureClass)
{
ESRI.ArcGIS .esriSystem .IName name=(ESRI.ArcGIS .esriSystem .IName)vs.Read ();
this.m_featureClass =(IFeatureClass)name.Open ();
}
}
public void Save(ESRI.ArcGIS .esriSystem .IVariantStream vs)
{
vs.Write (this.m_snapAgentName);
vs.Write (this.m_isSnapWorking );
vs.Write (this.m_hitPartType.ToString ());
if(this.m_featureClass !=null)
{
vs.Write (true);
IDataset dataset=(IDataset)this.m_featureClass ;
vs.Write (dataset.FullName );
}
else
{
vs.Write (false);
}
}
#endregion
}
public class DefaultSnapAgentEnvironment:ISnapAgentEnvironment
{
private double m_tolerance;
private SnapToleranceUnit m_snapToleranceUnit;
private ArrayList m_snapAgentArray;
///
/// 用于转换误差单位
///
private IActiveView m_activeView;
///
/// 如果误差单位为地图单位,那么可以调用这个构造函数。
/// 如果误差单位为象素。那么应该调用有参数的构造方法。
/// 如果在调用时不能确定参数activeView,那么也可以先调用该方法构造对象。
/// 然后用属性ActiveView来设置该参数的值。
///
public DefaultSnapAgentEnvironment():this(null)
{
}
public DefaultSnapAgentEnvironment(IActiveView activeView)
{
m_snapAgentArray=new ArrayList ();
m_tolerance=7;
m_snapToleranceUnit=SnapToleranceUnit.UnitPixels;
this.m_activeView=activeView;
}
///
/// 用于转换误差的单位。如果没有设置,或者设置为null,
/// 那么误差的单位将不会被转换,而直接被认为是地图单位。
///
public IActiveView ActivView
{
set
{
this.m_activeView=value;
}
get
{
return this.m_activeView;
}
}
#region ISnapAgentEnvironment 成员
public void AddSnapAgent(ISnapAgent agent)
{
if(agent==null)
{
return;
}
if(this.m_snapAgentArray.Contains(agent))
{
return;
}
this.m_snapAgentArray.Add(agent);
}
public void ClearSnapAgent()
{
this.m_snapAgentArray.Clear();
}
///
/// 如果索引越界,那么返回null,而不会抛出异常。
///
///
///
public ISnapAgent GetSnapAgent(int index)
{
if(index=0)
{
return (ISnapAgent)this.m_snapAgentArray[index];
}
else
{
return null;
}
}
///
/// 如果不存在,回返回null
///
///
///
ISnapAgent ls.gis.Editor.ISnapAgentEnvironment.GetSnapAgent(string name)
{
ISnapAgent retAgent=null;
int retAgentIndex=-1;
for(int index=0; index {
retAgent=(ISnapAgent)this.m_snapAgentArray[index];
if(retAgent.Name.Equals(name))
{
retAgentIndex=index;
break;
}
}
return GetSnapAgent(retAgentIndex);
}
public void RemoveSnapAgent(string name)
{
ISnapAgent retAgent=null;
int retAgentIndex=-1;
for(int index=0; index {
retAgent=(ISnapAgent)this.m_snapAgentArray[index];
if(retAgent.Name.Equals(name))
{
retAgentIndex=index;
break;
}
}
this.RemoveSnapAgent(retAgentIndex);
}
///
///
///
///
public void RemoveSnapAgent(int index)
{
if(index<0||index>=this.m_snapAgentArray.Count)
{
return ;
}
this.m_snapAgentArray.RemoveAt(index);
}
public bool SnapPoint(IPoint point)
{
for(int index=0;index {
ISnapAgent agent=(ISnapAgent)this.m_snapAgentArray[index];
if(agent.Snap(null,point,ConvertTolerance(this.m_tolerance)))
{
return true;
}
}
return false;
}
public int SnapAgentCount
{
get
{
// TODO: 添加 FeatureSnapAgentEnvironment.SnapAgentCount getter 实现
return this.m_snapAgentArray.Count;
}
}
public double SnapAgentTolerance
{
get
{
// TODO: 添加 FeatureSnapAgentEnvironment.SnapAgentTolerance getter 实现
return this.m_tolerance;
}
set
{
this.m_tolerance=value;
}
}
public SnapToleranceUnit SnapToleranceUnit
{
get
{
return this.m_snapToleranceUnit;
}
set
{
this.m_snapToleranceUnit=value;
}
}
#endregion
private double ConvertTolerance(double tolerance)
{
double retValue=tolerance;
if(this.m_activeView ==null)
{
//不能做转换
retValue=tolerance;
}
else
{
if(this.m_snapToleranceUnit.Equals (SnapToleranceUnit.UnitPixels))
{
//需要转换
retValue=ls.gis.Common .CommonCooperation.ConvertPixelsToMapUnits (this.m_activeView
,tolerance);
}
else
{ //不需要转换
retValue=tolerance;
}
}
return retValue;
}
private double ConvertTolerance()
{
return this.ConvertTolerance (this.m_tolerance);
}
}
========
ArcEngine实现捕捉节点
http://blog.sina.com.cn/s/blog_4d0b75870100o960.html//获取最近的结点,然后在 OnMouseMove中显示
//pnt:鼠标移动点
//mapSize:设置的地理范围
public static IPoint GetNearestVertex(IActiveView actview, IPoint pnt, double mapSize)
{
IPoint vetex = null;
IPoint hitPnt=new PointClass();
IHitTest hitTest = null;
IPointCollection pntColl =new MultipointClass();
IProximityOperator prox = null;
double hitdis=0;
int hitpartindex=0,hitsegindex=0;
Boolean rside = false;
IFeatureCache2 featCache = new FeatureCacheClass();
double pixelSize = ConvertMapUnitsToPixels(actview, mapSize); //将地理范围转化为像素
featCache.Initialize(pnt, pixelSize); //初始化缓存
for (int i = 0; i < actview.FocusMap.LayerCount; i++)
{
//只有点、线、面并且可视的图层才加入缓存
IFeatureLayer featLayer =(IFeatureLayer) actview.FocusMap.get_Layer(i);
if (featLayer != null && featLayer.Visible == true &&
(featLayer.FeatureClass.ShapeType==esriGeometryType.esriGeometryPolyline ||
featLayer.FeatureClass.ShapeType == esriGeometryType.esriGeometryPolygon ||
featLayer.FeatureClass.ShapeType == esriGeometryType.esriGeometryPoint))
{
featCache.AddFeatures(featLayer.FeatureClass, null);
for (int j = 0; j < featCache.Count; j++)
{
IFeature feat = featCache.get_Feature(j);
hitTest =(IHitTest ) feat.Shape;
//捕捉节点,另外可以设置esriGeometryHitPartType,捕捉边线点,中间点等。
if (hitTest.HitTest(pnt, mapSize, esriGeometryHitPartType.esriGeometryPartVertex,
hitPnt, ref hitdis, ref hitpartindex, ref hitsegindex, ref rside))
{
object obj=Type.Missing ;
pntColl.AddPoint(hitPnt,ref obj,ref obj);
break;
}
}
}
}
prox =(IProximityOperator)pnt;
double minDis=0, dis=0;
for (int i = 0; i < pntColl.PointCount; i++)
{
IPoint tmpPnt=pntColl.get_Point(i);
dis= prox.ReturnDistance(tmpPnt);
if (i == 0)
{
minDis = dis;
vetex = tmpPnt;
}
else
{
if (dis < minDis)
{
minDis = dis;
vetex = tmpPnt;
}
}
}
return vetex;
}
========