內蒙古java團隊

          j2se,j2ee開發組
          posts - 139, comments - 212, trackbacks - 0, articles - 65
            BlogJava :: 首頁 :: 新隨筆 :: 聯系 :: 聚合  :: 管理

          ArcEngine中實現捕捉功能

          Posted on 2007-03-08 16:42 帥子 閱讀(3232) 評論(2)  編輯  收藏 所屬分類: J2EE技術專區
          ArcEngine中實現捕捉功能

          捕捉功能主要使用ArcEngine中的兩個接口

          1. IHitTest用于作點擊測試
          2. IFeatureCache 用于建立做緩存
          由于數據庫中有多個FeatureClass ,而每個FeatureClass又可以做多種點擊測試
          所以這里有會有好幾種捕捉方案。
          我們稱呼每一個可以執行捕捉的對象叫捕捉代理,所有的代理在一個捕捉環境中
          方案1:每個代理負責測試一種FeatureClass的一種點擊方式
          方案2:每個代理負責測試一種FeatureClass的所有點擊方式
          方案3:一代理負責測試所有的FeatureClass的一種點擊方式
          方案4:一個代理負責測試所有FeatureClass的所有點擊方式
          在實際使用過程中 我們使用的是第一種方案。但是我個人認為第二種方案比較好。當然這只是個人推測
          沒有測試數據證明。
          下面給出第一種方案的代碼:
          /// <summary>
          ?/// IFeatureSnapAgent 的摘要說明。
          ?/// </summary>
          ?public interface IFeatureSnapAgent:ISnapAgent,ISnapAgentFeedback
          ?{
          ??IFeatureCache FeatureCache
          ??{
          ???get;
          ??}
          ??IFeatureClass? FeatureClass
          ??{
          ???get;
          ???set;
          ??}
          ??esriGeometryHitPartType HitPartType
          ??{
          ???get;
          ???set;
          ??}
          ??/// <summary>
          ??/// 為捕捉連接事件,當捕捉發生的時候,就會觸發事件。
          ??/// </summary>
          ??/// <param name="handler"></param>
          ??void AddSnapedEventHandler(GeometrySnapedEventHandler handler);
          ??/// <summary>
          ??/// 不再監聽捕捉事件
          ??/// </summary>
          ??/// <param name="handler"></param>
          ??void RemoveSnapedEventHandler(GeometrySnapedEventHandler handler);
          ?}
          ?/// <summary>
          ?/// 默認的要素捕捉代理
          ?/// </summary>
          ?public class DefaultFeatureSnapAgent :IFeatureSnapAgent,IEditEvents,ESRI.ArcGIS .esriSystem .IPersistVariant??
          ?{
          ??#region 構造函數
          ??/// <summary>
          ??/// 為代理指定別名。注意該代理目前還沒有關聯到任何目標FeatureClass
          ??/// 要使得該代理起作用,必須要為他設置FeatureClass.
          ??/// </summary>
          ??/// <param name="name">名稱(請確保唯一)</param>
          ??public DefaultFeatureSnapAgent(string name):this(name,null)
          ??{
          ???
          ??}
          ??/// <summary>
          ??/// 將使用該FeatureClass的別名做代理的名稱
          ??/// </summary>
          ??/// <param name="feaClass"></param>
          ??public DefaultFeatureSnapAgent(IFeatureClass feaClass):this(feaClass.AliasName,feaClass)
          ??{

          ??}
          ??/// <summary>
          ??/// 完全初始化捕捉代理
          ??/// </summary>
          ??/// <param name="name">名稱(請確保唯一)</param>
          ??/// <param name="feaClass">目標FeatureClass</param>
          ??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;
          ??/// <summary>
          ??/// FeatureClass緩沖區。
          ??/// </summary>
          ??private IFeatureCache m_featureCache;
          ??/// <summary>
          ??/// 該代理將捕捉在該FeatureClass上的Feature.和Geometry
          ??/// </summary>
          ??private IFeatureClass m_featureClass;
          ??/// <summary>
          ??/// 點擊測試的有效類型。
          ??/// </summary>
          ??protected esriGeometryHitPartType m_hitPartType;
          ??/// <summary>
          ??/// 緩沖區對象是否已經被創建了。跟是否建立了緩沖沒有關系。
          ??/// </summary>
          ??private bool?? m_bCacheHasCreated;
          ??
          ??/// <summary>
          ??/// 緩沖區對象
          ??/// </summary>
          ??public IFeatureCache FeatureCache
          ??{
          ???get
          ???{
          ????return m_featureCache;
          ???}
          ??}
          ??/// <summary>
          ??/// 目標FeatureClass。SnapAgent將針對該FeatureClass做捕捉
          ??/// </summary>
          ??public IFeatureClass FeatureClass
          ??{
          ???get
          ???{
          ????return m_featureClass;
          ???}
          ???set
          ???{
          ????m_featureClass=value;
          ???}
          ??}
          ??
          ??/// <summary>
          ??/// 點擊測試類型。哪些點擊類型會被測試
          ??/// </summary>
          ??public ESRI.ArcGIS.Geometry.esriGeometryHitPartType HitPartType
          ??{
          ???get
          ???{
          ????// TODO:? 添加 DefaultFeatureSnapAgent.HitPartType getter 實現
          ????return m_hitPartType;
          ???}
          ???set
          ???{
          ????
          ????m_hitPartType=value;
          ???}
          ??}

          ??/// <summary>
          ??///? 創建緩沖區對象。
          ??/// </summary>
          ??private void CreateFeatureCache()
          ??{
          ???m_featureCache=new ESRI.ArcGIS.Carto.FeatureCacheClass();
          ???m_bCacheHasCreated=true;
          ??}
          ??/// <summary>
          ??///? 填充緩沖區。如果還沒有創建緩沖區對象,就先創建緩沖區對象。
          ??///? 如果已經擁有緩沖區,而且當前點依然在該緩沖區內部,那么不會填充生成新的緩沖。
          ??///? 由于緩沖是在捕捉方法內部被使用的。所以可以保證m_featureClass必然不會為空引用。
          ??/// </summary>
          ??/// <param name="point">當前點</param>
          ??/// <param name="size">緩沖區大小</param>
          ??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);
          ???}
          ??}
          ??/// <summary>
          ??/// 添加事件偵聽者。捕捉發生后,事件將會被發送到該偵聽者。
          ??/// </summary>
          ??/// <param name="handler"></param>
          ??public void AddSnapedEventHandler(GeometrySnapedEventHandler handler)
          ??{
          ???m_snapSubsciber+=handler;
          ??}
          ??/// <summary>
          ??/// 移去事件偵聽者。
          ??/// </summary>
          ??/// <param name="handler"></param>
          ??public void RemoveSnapedEventHandler(GeometrySnapedEventHandler handler)
          ??{

          ???m_snapSubsciber-=handler;
          ??}
          ??#endregion
          ??#region ISnapAgent 成員
          ??private string m_snapAgentName;
          ??/// <summary>
          ??/// SnapAgent是否在工作。代表用戶是打開還是關閉了SnapAgent
          ??/// 初始化的時候默認是打開的。
          ??/// </summary>
          ??private bool?? m_isSnapWorking;
          ??public string Name
          ??{
          ???get
          ???{
          ????return m_snapAgentName;
          ???}
          ??}
          ??public bool IsWorking()
          ??{
          ???return this.m_isSnapWorking ;
          ??}
          ??/// <summary>
          ??///? 捕捉。
          ??/// </summary>
          ??/// <param name="metry"></param>
          ??/// <param name="snapPoint"></param>
          ??/// <param name="tolerance"></param>
          ??/// <returns></returns>
          ??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<featureCount;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;
          ??}
          ??
          ??/// <summary>
          ??/// 打開捕捉代理
          ??/// </summary>
          ??public void TurnOn()
          ??{
          ???this.m_isSnapWorking=true;
          ??}
          ??/// <summary>
          ??/// 關閉捕捉代理
          ??/// </summary>
          ??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 成員
          ??/// <summary>
          ??/// 名字是一個agent的唯一標志。
          ??/// </summary>
          ??/// <param name="obj"></param>
          ??/// <returns></returns>
          ??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;
          ??/// <summary>
          ??/// 用于轉換誤差單位
          ??/// </summary>
          ??private IActiveView m_activeView;
          ??/// <summary>
          ??/// 如果誤差單位為地圖單位,那么可以調用這個構造函數。
          ??/// 如果誤差單位為象素。那么應該調用有參數的構造方法。
          ??/// 如果在調用時不能確定參數activeView,那么也可以先調用該方法構造對象。
          ??/// 然后用屬性ActiveView來設置該參數的值。
          ??/// </summary>
          ??public DefaultSnapAgentEnvironment():this(null)
          ??{
          ???
          ??}
          ??public DefaultSnapAgentEnvironment(IActiveView activeView)
          ??{
          ???m_snapAgentArray=new ArrayList ();
          ???m_tolerance=7;
          ???m_snapToleranceUnit=SnapToleranceUnit.UnitPixels;
          ???this.m_activeView=activeView;
          ??}
          ??/// <summary>
          ??///? 用于轉換誤差的單位。如果沒有設置,或者設置為null,
          ??///? 那么誤差的單位將不會被轉換,而直接被認為是地圖單位。
          ??/// </summary>
          ??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();
          ??}
          ??/// <summary>
          ??/// 如果索引越界,那么返回null,而不會拋出異常。
          ??/// </summary>
          ??/// <param name="index"></param>
          ??/// <returns></returns>
          ??public ISnapAgent GetSnapAgent(int index)
          ??{
          ???if(index<this.m_snapAgentArray.Count&&index>=0)
          ???{
          ????return (ISnapAgent)this.m_snapAgentArray[index];
          ???}
          ???else
          ???{
          ????return null;
          ???}
          ??}
          ??/// <summary>
          ??/// 如果不存在,回返回null
          ??/// </summary>
          ??/// <param name="name"></param>
          ??/// <returns></returns>
          ??ISnapAgent ls.gis.Editor.ISnapAgentEnvironment.GetSnapAgent(string name)
          ??{
          ???ISnapAgent retAgent=null;
          ???int retAgentIndex=-1;
          ???for(int index=0; index<this.m_snapAgentArray.Count;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<this.m_snapAgentArray.Count;index++)
          ???{
          ????retAgent=(ISnapAgent)this.m_snapAgentArray[index];
          ????if(retAgent.Name.Equals(name))
          ????{
          ?????retAgentIndex=index;
          ?????break;
          ????}
          ???}
          ???this.RemoveSnapAgent(retAgentIndex);
          ??}
          ??/// <summary>
          ??///
          ??/// </summary>
          ??/// <param name="index"></param>
          ??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<this.m_snapAgentArray.Count;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);
          ??}
          ??

          ?}


          評論

          # re: ArcEngine中實現捕捉功能  回復  更多評論   

          2008-01-23 16:21 by cai_zd
          ISnapAgent在ArcEngine中沒有找到

          # re: ArcEngine中實現捕捉功能  回復  更多評論   

          2009-01-08 12:34 by ddddddd
          一大堆接口都不是AE里的
          應該叫“ArcObjects中實現捕捉功能”
          主站蜘蛛池模板: 会泽县| 承德市| 乐陵市| 托里县| 漳州市| 和田市| 靖西县| 临西县| 岳普湖县| 团风县| 南投市| 神木县| 本溪| 武邑县| 靖江市| 白河县| 江川县| 咸丰县| 凤山市| 平南县| 伊川县| 淮安市| 乌拉特前旗| 三亚市| 修武县| 偏关县| 福安市| 微山县| 镇巴县| 易门县| 西畴县| 平定县| 东丰县| 咸阳市| 张家川| 安溪县| 曲麻莱县| 卢氏县| 金秀| 沙湾县| 陆良县|