TopMap

   GIS论坛-GIS空间站社区日志网络日志 发表日志

网络日志
ArcEngine中对Feature的编辑

对Feature的编辑分为以下几个部分
1.新建
2.修改
3.删除
涉及到的接口有以下几个
IWorkspaceEdit
IFeatureClass
IFeatureCursor
IFeature
其中IWorkspaceEdit用于启动编辑 开始编辑操作 结束编辑操作 结束编辑
IFeatureClass 是数据的所在地
IFeatureCursor 是一个游标 提供访问数据的接口和修改数据的接口
IFeature 是对象的代表 我们要编辑的目标
编辑的过程如下:
1.添加一个Feature
//假设space是一个IWorkspaceEdit
//参数表示是否需要使用Undo/Redo功能,该功能的粒度是EditOperator.
spaceEdit.StartEditing(false);
spaceEdit.StartEditOperator();
  //添加一个Feature
  IFeature newFea=feaClass.createFeature();
  //为Feature 添加属性 设置图形
  newFea.Store();//保存属性和图形
  spaceEdit.StopEditOperator();//结束编辑操作
//结束编辑过程
//参数表示是否保存编辑
spaceEdit.StopEditing(true);
2.添加多个Feature
  添加多个Feature也可以向上面一样 使用多次就可以了
  当时也可以使用IFeatureCursor来添加数据
 3.修改Feature
   添加Feature中的修改属性和图形部分就是
   每次修改后一定要调用Store方法 这样变化才可以保存下来
 4.删除
   IFeature 有一个方法Delete 可以用于删除 当时经过测试发现对Shapefile
   会抛出异常来。
   IFeatureCuror有一个DeleteFeature方法 可以用来删除当前的Feature ,经测试
  对所有的数据源类型都可以使用。
 
  注意事项
  1.不能设置Feature的OID
  2.不能设置Feature的Area
  3.不能设置Feature的Lenght
  4.不能设置Feature的Shape字段,需要调用单独的方法来给Feature关联几何图形。
阅读全文 | 编辑 | 删除 | 2006-4-4 12:03:37 by zhulgxg
ArcEngine 中ITool的使用(1)

目前知道的有两个特性

1.每次激活的时候调用Onclick()

2.每次被别的工具替换的时候调用Deactive()。如果该方法返回true那么可以被替换下来。如果返回false,那么不能被替换下来。


阅读全文 | 编辑 | 删除 | 2006-4-4 11:40:38 by zhulgxg
ArcEngine中对象不能及时释放资源的错误

ArcEngine 中存在一些错误。其中最有名的就是对象不能释放资源的问题。
比如打开了一个Shapefile ,除非程序关闭否则就没有办法释放对Shapefile的控制
还有读取ServerStyle文件的时候那个StyleItemEnum只能使用一次。第二次就会出错,
如果在短时间内搜索多个FeatureClass这样就会产生多个FeatureCursor,那么就会出现
打开的游标数目过多或者不能打开更多的表这样的错误。
这些错误都是由于对象不能释放资源所造成的。
可以使用以下方法来释放(C#):
//其中relObj就是要释放的对象。
System.Runtime.InteropServices.Marshal.ReleaseComObject(relObj);
如果要确保被释放了。那么可以循环调用该方法 直到这个方法返回0为止
阅读全文 | 编辑 | 删除 | 2006-4-4 11:28:16 by zhulgxg
ArcEngine中拓扑的使用

拓扑(ITopology)的使用包括
1.建立拓扑
2.验证拓扑
3.编辑过程中保证拓扑的正确
4.查询系统中存在的拓扑
1.首先 来看看建立拓扑
    Topology实现了ITopology这个接口 但是给类是不能用来创建对象的。
  必须要通过调用 ITopologyContainer::CreateTopology这个方法来建立一个Topology
  FeatureDataset 实现了ITopologyContainer这个接口。那么 这就是说拓扑只能在一个
  FeatureDataset的范围内建立。而不能独立存在于Workspace中。这样做的原因是需要保证
  参与同一个拓扑的FeatureClass具有同一个投影坐标系统。 建立拓扑后需要将ObjectClass
  加入到拓扑中去。这样这个拓扑就可以用来验证这几个ObjectClass 的对象之间的关系了。
     验证关系就要有规则,规则是由ITopologyRule来表达的。ITopologyRule必须要被
   加入到一个ITopologyRuleContainer中去。而Topology实现了这个接口。
   一个ITopologyRule用来表达两个ObjectClass的对象之间的某个关系。
     具体代码参看接口就可以了。
 2.验证拓扑
     ITopology有一个方法 ValidateTopology 用来验证指定区域内的拓扑。需要注意 没有版本
   的拓扑可以在 任何时候验证。而有版本的拓扑必须在编辑回话中验证。
 3.拓扑编辑
   1.移动共用点
    1.首先需要打开拓扑 建立拓扑图(ITopologyGraph)
    代码如下:
    //topoLayer 是一个打开的拓扑图层
    ITopologyGraph pTG=topoLayer.Topology.Cache;
  pTG.Build(pA.Extent,false);
  2.然后 需要获得当前节点或者边 这个操作要使用拓扑图的点击测试
  ITopologyElement topeEle
  pTG.HitTest(... ref topeEle);
  这个方法在点击测试成功的时候返回true.而且会通过topeEle这个ref 参数将选中的元素(点或者边)
  返回.
  3.还有一种获取节点的方法
    首先调用拓扑图的Select方法 选中点击测试的元素(pTG.Select)
    然后可以查询拓扑图的选中节点集合 就可以找到该节点(pTG.NodeSelection)
  4.为该元素使用一个Feedback.
   //其中 pNode 就是当前节点 sr 是参考坐标系 可以使用null
   //还有给Feedback设置Display
    m_pNodeFeedback =pTG.GetSplitMoveNodeFeedback(pNode,false,sr);
    m_pNodeFeedback.Display= activeView.ScreenDisplay;
  5.在鼠标移动的时候 调用Feedback的MoveTo 方法。
   if(m_pNodeFeedback!=null)
   {
    //activeView 是活动的试图
    //首先要把将点坐标转换为地图中的坐标。
    //然后调用MoveTo 方法    
    IPoint pt=activeView.ScreenDisplay.DisplayTransformation.ToMapPoint(X,Y);
    m_pNodeFeedback.MoveTo(pt);
   }
    6.在鼠标释放的时候
      //获取拓扑图
        ITopologyGraph pTG=topoLayer.Topology.Cache;
        //转换坐标   
      IPoint pt=pA.ScreenDisplay.DisplayTransformation.ToMapPoint(X,Y);
      //获得正在做拓扑编辑的元素        
     ITopologyNode pTN=(ITopologyNode)m_pTopoElement;
     //实施拓扑编辑
    pTG.SplitMoveNode(pTN,pt,false);
    //提交拓扑编辑结果
    IEnvelope pE;
    pTG.Post(out pE);
 4.查询系统中的拓扑
   还是ITopologyContainer 这个接口 这个接口有FeatureDataset这个唯一的实现。
   CreateTopology 建立一个新的拓扑
   DefaultClusterTolerance The default cluster tolerance as per the topology engine.
   MaximumClusterTolerance The maximal cluster tolerance as per the topology engine.
   MinimumClusterTolerance The minimal cluster tolerance as per the topology engine.
   Topology 通过索引打开拓扑.
   TopologyByID 通过ID打开拓扑.
   TopologyByName 通过名字打开拓扑
   TopologyCount  拓扑的数目

 


阅读全文 | 编辑 | 删除 | 2006-4-4 11:15:28 by zhulgxg
ArcEngine中版本的使用

使用版本的过程分为以下几个步骤
1.将Workspace或者数据集注册为使用版本的Workspace或者数据集
IVersionedObject verObj= ds as IVersionedObject;//假设ds 是一个数据集
if(verObj!=null&&(!verObj.pVerdObj.IsRegisteredAsVersioned))
{
 //数据集可以被注册而且还没有被注册为版本数据集
 //下面的方法 如果使用参数 false 那么表示注册为没有版本的数据
 //也就是反注册
 verObj.RegisterAsVersioned(true);
}
2.获取版本数据
 获取版本数据的过程比较简单。在连接数据库的时候 需要提供版本字符串。
 默认是使用sde.Default这个版本。如果使用其他版本字符串就会获得其他版本的数据。
3.建立新版本
 //假设space 是一个Workspace 而且是一个企业数据库的Workspace。个人数据库和文件工作空间是
 //没有版本功能的。
 IVersionedWorkspace pVerWS=(IVersionedWorkspace)space;
 IVersion pV=pVerWS.DefaultVersion;//上一级版本 这里使用默认版本作为上一级版本   
 IVersion pVC=pV.CreateVersion(verName); //建立版本   
 pVC.Description=verDesc;//版本的描述
 pVC.Access=esriVersionAccess.esriVersionAccessPrivate;//版本的存取策略为私有
 pNewVerWS=(IVersionedWorkspace)pVC;//获取使用新版本的Workspace的一种快捷方式
4.合并版本数据
 合并数据使用IVersionEdit接口
 这个接口有VersionedWorkspace 实现。
 下面介绍这个接口
 CanPost 当前正在编辑的版本是否可以提交到目标版本中去 。
  CommonAncestorVersion 当前版本和目标版本的共同祖先 。
  ConflictClasses 有冲突的Class。
  ModifiedClasses 在两个版本中发生变化的Class 。
  Post 提交版本数据
  PreReconcileVersion  目标版本在检测冲突之前的状态(?)。
  Reconcile 测试数据是否冲突 如果返回true表示有冲突
  ReconcileVersion  目标版本在冲突检测开始的时候的状态(?)
  StartEditingVersion 目标版本开始编辑的时候的状态 (?)
  在提交数据之前 一定要调用Reconcile 否则很有可能会返回错误。

5.浏览工作版本元数据
 浏览版本元数据是指统计工作空间中一共有哪些版本。某个指定的版本的父亲或祖先是谁?
 他又有哪些派生的版本?
 IVersionInfo 接口提供了这些信息
 下面是IVersionInfo接口的详细信息:
 Access 接口的访问策略
 Ancestors 版本的所有祖先,按照由近到远的次序排列
 Children 该版本的直接派生版本。
 Created 创建的时间
 Description 版本的描述
 IsOwner 当前用户是不是拥有该版本
 Modified 最后修改时间
 Parent 版本的直接父亲接电
 VersionName 版本的名称
 
 注意VersionInfo 实现了上述接口 但是VersionInfo 不是一个可以用来创建对象的类。我们只能通过
 别的方式获取他
 IVersionedWorkspace.FindVersion("目标版本名称");
 或者
 IVersionedWorkapce.Versions 获取所有当前用户可以获得的版本。包括自己建立 别人建立的public 和protected的版本
 但是如果别人建立的版本是protected 的那么 你就只能看到数据。不能编辑。


阅读全文 | 编辑 | 删除 | 2006-4-4 11:14:47 by zhulgxg
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);
  }
  

 }


阅读全文 | 编辑 | 删除 | 2006-4-3 10:57:29 by zhulgxg
ArcEngine影像图配准

影像图配准主要包括以下几个方面
1.打开影像图
2.配准
3.影像图入库/保存
1.打开影像图的代码以前已经写过了。
2.配准
  配准 主要使用IGeoReference这个接口来完成工作。
  还有使用ActiveView来进行坐标转换,将MapControl中鼠标的点击位置 转换为
  地图和影像图上的坐标。
  下面介绍IGeoReference接口
   首先RasterLayer实现了这个接口
   CanGeoRef 监测该图层是否可以做配准
   PointsTransform 将鼠标的位置 转换为栅格文件上的相对坐标。
   Rectify 将纠正的结果保存为一个新的栅格文件 相当于另存为
   Register 纠正的结果生成World文件 和栅格文件保存在同一个目录下
   Reset 取消纠正 但是Register 之前的操作不能恢复。
  
   最重要的是下面三个
   Shift  一点纠正 就是平移
   TwoPointsAdjust 两点配准 有一定的缩放
   Warp 三点或以上配准
  
   注意事项
   1.每次Register是一个标志阶段
    这每次配准的过程中 必须把上次Register 以来的所有配准点数据都使用上。
    例如:
    首先Register了
    然后 1.使用了一点平移
         2.接下来 又接受了一个点 这个时候就要使用 两点配准。
         3.接下来 又接受了一个点 这个时候就要使用 三点配准了。
   2.配准一般还有一个附加的功能
     就是 让用户保存每次的配准过程 并且 提供每次配准过程的精度。这个需要自己补充。
3.入库/金字塔
  直接来代码:
     IRasterProps props=(IRasterProps)this.pRasterLayer.Raster;
    m_rasEnv=props.Extent;
    IBasicRasterSdeConnection pBasic=new BasicRasterSdeLoader();
    //提供连接信息
    pBasic.ServerName ="服务期名称" ;
    pBasic.Instance ="端口号" ;
    pBasic.UserName ="用户名" ;
    pBasic.Password ="密码" ;    
    //提供影像图
    pBasic.Raster =this.pRasterLayer .Raster ;  
    //名称
    pBasic.SdeRasterName=rasterNameInDB;
    
    IRasterSdeServerOperation pRo=(IRasterSdeServerOperation)pBasic;
    //导入数据
    try
    {     
     pRo.Create();
     pRo.ComputeStatistics();
    }
    catch(Exception ex)
    {
     System.Windows .Forms .MessageBox .Show ("影像数据入库失败!"+ex.Message );
     return;
    }
    //建立金字塔
    IRasterSdeStorage2  pRs=(IRasterSdeStorage2)pRo;
    pRs.PyramidOption=esriRasterSdePyramidOptEnum.esriRasterSdePyramidBuildSkipFirstLevel;
    pRs.PyramidResampleType=rstResamplingTypes.RSP_BilinearInterpolation;
    pRo.BuildPyramids();
    这个影像图 就这样到数据库中去了
    
    注意
    一般自己还要建立一个关于影像图的原数据表 。用来记录那些影像图是属于自己的。还有名称的转换问题
    因为中文名称是不可以的。              
 


阅读全文 | 编辑 | 删除 | 2006-4-3 10:24:15 by zhulgxg
ArcEngine 渲染的使用

1.Feature的基本渲染方法
 Feature的常用的绘制方法包括:
  1.简单绘制
  2.唯一值绘制/多字段唯一值绘制
  3.点密度/多字段点密度绘制
  4.数据分级绘制
  5.质量图(饼图/直方图)
  6.按比例尺渲染
  7.比例符号渲染
 
  1.简单渲染
  简单渲染是ArcEngine的默认渲染,我们打开一个FeatureClass,建立一个FeatureLayer的时候,
如果没有给FeatureLayer设置Renderer那么使用的就是简单渲染。简单渲染对整个图层中的所有Feature
使用同一种方式显示。
简单渲染在ArcEngine中用ISimpleRenderer来表示。
 ISimpleRenderer的使用方式如下:
 //假设layer是一个IFeatureLayer,获取IGeoFeatureLayer
  IGeoFeatureLayer geoLayer=layer as IGeoFeatureLayer;
  //构造SimpleRenderer
  ISimpleRenderer renderer=new SimpleRendererClass();
  renderer.description="简单的渲染一下";
  renderer.Label="符号的标签";
  //假设sym是一个和该图层中Geometry类型对应的符号;
  renderer.Symbol=sym;
  //为图层设置渲染,注意需要刷新该图层。
  geoLayer.Renderer=renderer;
  2.独立值/多字段独立值渲染
  独立值/多字段独立值渲染,根据Feature的某一个字段的数据或某几个字段的组合结果来确定符号。
  具有相同值或相同组合值的Feature,使用一样的符号。在使用多个字段的使用,每个字段的取值之间
  使用分割符来连接。字段的取值顺序和在Renderer中设置的一样。
  基本使用方式如下:
  //假设layer是一个IFeatureLayer,获取IGeoFeatureLayer
  IGeoFeatureLayer geoLayer=layer as IGeoFeatureLayer;
  //构造一个UniqueValueRenderer
  IUniqueValueRenderer renderer=new UniqueValueRendererClass();
  //假设使用两个字段来渲染
  renderer.FieldCount=2;
  //假设YSLX字段表示要素类型
  //假设YSYT字段表示要数用途
  renderer.set_Field(0,"YSLX");
  renderer.set_Field(1,"YSYT");
  //字段之间使用 | 来连接(默认取值)
  renderer.FieldDelimiter="|";
  //设置默认符号
  renderer.DefaultSymbol=defaultSymbol;
  renderer.DefaultLabel="默认Label";
  //添加值
  renderer.addValue("房屋|民居","民居房屋",MJSymbol);
  renderer.addValue("房屋|商业用地","商业用地",SYSymbol);
  ...
  //还可以通过set_Symbol,set_Heading、set_Value来修改上述设置。
  geoLayer.Renderer=renderer.
  3.点密度/多字段点密度
  点密度图通过在Feature的图形上打点来表示数据的数多,点越密集表示数据量越大。
  还可以使用多字段的点密度图。这个使用同一个Feature上就可以显示几种不同的点。
  注意点密度图有一个特殊的地方:
    点密度图使用的符号是面状符号。而其中有需要包括点状符号。
    接口使用如下:
     IDotDensityRenderer renderer=new DotDensityRendererClass ();
   IRendererFields flds=(IRendererFields)renderer;
   flds.AddField("MJ ","面积");
   flds.AddField("RK","人口");
   IDotDensityFillSymbol ddSym=new DotDensityFillSymbolClass();
   ISymbolArray symArray=(ISymbolArray)ddSym;
   symArray.AddSymbol(mjSymbol);
   symArray.AddSymbol(rkSymbol);
   ddSym.Outline =(ILineSymbol)outlineSymbol ;   
   ddSym.DotSize =10 ;
   ddSym.FixedPlacement=true;   
   
   renderer.DotDensitySymbol =ddSym;
   renderer.DotValue=20 ;
   renderer.MaintainSize=this.m_dotdensityParam .MaintainSize ;
   IGeoFeatureLayer geoLayer=(IGeoFeatureLayer)layer ;
   geoLayer.Renderer =(IFeatureRenderer)renderer;
 4.数据分级绘制(使用IClassBreaksRenderer)
 5.饼图/直方图(使用IChartRenderer)
 6.按比例尺渲染(使IScaleDependentRenderer)
 7.比例符号渲染(使用 IProportionalSymbolRenderer )
2.图例的使用
  图例的使用通过ILegendInfo接口。每个Renderer都实现了该接口,但是有时候该实现不好用,
  所以也可以自己实现该接口。实现过程是比较简单的。
3.渲染层次
  使用ILevelRender 接口。该接口可以指定一 当前的Level(-1)表示绘制全部。
  然后 提供一个符号数组 ,注意每个符号要指定Level .如果不指定就默认为0。

4.透明度控制
  透明度控制使用 ITransparencyRenderer 接口。该接口允许指定一个字段,字段取值用来表示透明度
  注意 透明度的取值在0--100之间。
5.数据正规化
  数据正规化用 IDataNormalization 接口来表示。该接口提供了几种正规化表示方法。
6.部分渲染
  部分渲染通过使用IDataExclusion  来实现。该接口允许提供过滤语句来过滤掉不需要渲染的Feature。
  同时也可以给他们制定特殊的符号。同时控制是否显示
7.旋转控制
  旋转控制通过使用IRotationRenderer 接口来表示。该接口要求提供旋转角度的字段。同时要求提供旋转的
  方法。
8.数据样本
 IDataSampling  没有使用过。
9.外表关联
 ITable dispTable=((IDisplayTable)feaLayer).DisplayTable ;//图层
 ITable attTable;//外表
 IMemoryRelationshipClassFactory fac=new MemoryRelationshipClassFactoryClass ();
 IRelationshipClass relClass=fac.Open("JZMJ",(IObjectClass)dispTable,"ZDDJH",
   IObjectClass)attTable,"G03",
   "Forward","Backward",
   esriRelCardinality.esriRelCardinalityOneToOne);
 IDisplayRelationshipClass dispRelClass=feaLayer as IDisplayRelationshipClass ;
 dispRelClass.DisplayRelationshipClass(relClass,esriJoinType.esriLeftInnerJoin);
10.统计分析
   ITableHistogram  tableHistogram=new BasicTableHistogramClass ();
  tableHistogram.Table =((IDisplayTable)layer).DisplayTable  ;
  tableHistogram.Field =fieldName ;
  object valueArray=null, freq=null;
  IBasicHistogram basicHistogram=(IBasicHistogram)tableHistogram;
  basicHistogram.GetHistogram(out valueArray,out freq);
  IClassify classify=null;
   int breakNum=6;
   //分类方法
   switch(ClassifyMethod )
   {
    case ClassifyMethodName.lsClassifyMethodEqualInterval:
    {
     
      EqualIntervalClass  eq=new EqualIntervalClass ();
      eq.Classify (valueArray,freq,ref breakNum);
      classify=(IClassify)eq;
     
     break;
    }
    case ClassifyMethodName.lsClassifyMethodStandardDeviation:
    {
     
      StandardDeviationClass sd=new StandardDeviationClass ();
      IStatisticsResults stat= histogram as IStatisticsResults ;
      classify=sd as IClassify;
      classify.SetHistogramData (valueArray,freq);
      IDeviationInterval di=sd as IDeviationInterval ;
      di.DeviationInterval=1;
      di.Mean=stat.Mean;
      di.StandardDev=stat.StandardDeviation;
      classify.Classify (ref breakNum);
     
     break;
    }
    case ClassifyMethodName.lsClassifyMethodQuantile:
    {
     
      Quantile qc=new QuantileClass ();
      qc.Classify (valueArray,freq,ref breakNum);
      classify=qc as IClassify ;
     
     break;
    }
    case ClassifyMethodName.lsClassifyMethodNaturalBreaks:
    {
     
      NaturalBreaksClass nb=new NaturalBreaksClass ();
      nb.Classify (valueArray,freq,ref breakNum);
      classify=nb as IClassify ;
     
     break;
    }
    case ClassifyMethodName.lsClassifyMethodDefinedInterval:
    {
     DefinedIntervalClass di=new DefinedIntervalClass ();
     di.IntervalRange =this.m_classBreaksParam .Interval ;
     di.Classify (valueArray,freq,ref breakNum);
     classify=di as IClassify ;
     break;
    }
    default:
    {
    
     EqualIntervalClass  eq=new EqualIntervalClass ();
     eq.Classify (valueArray,freq,ref breakNum);
     classify=(IClassify)eq;
     break;
    
    }
   }   
   object o=classify.ClassBreaks ;
   System.Array breakArray= o as System.Array;
   现在breakArray中就是统计后的数据了。


阅读全文 | 编辑 | 删除 | 2006-3-29 11:36:46 by zhulgxg
JFreeChart建立一个Chart

import org.jfree.chart.ChartFactory;
import org.jfree.chart.ChartFrame;
import org.jfree.chart.JFreeChart;
import org.jfree.data.general.DefaultPieDataset;

public class First {

 public First() {
  super();
  // TODO Auto-generated constructor stub
 }
 /**
  * @param args
  */
 public static void main(String[] args) {
  // 准备数据
   DefaultPieDataset ds=new DefaultPieDataset();
   ds.setValue("中国",25.3);
   ds.setValue("美国",23.6);
   ds.setValue("欧洲",36.5);
   //构造Chart
   JFreeChart chart= ChartFactory.createPieChart(
     "PieChartDemo"//标题
     ,ds//数据
     ,true//是否显示图例
     ,true//是否显示Tooltip
     ,false//使用为URL。
     );
   //显示Chart
   ChartFrame chartFrame=new ChartFrame("First",chart);
   chartFrame.pack();
   chartFrame.setVisible(true);
 }

}


阅读全文 | 编辑 | 删除 | 2006-3-28 13:01:24 by zhulgxg
AE数据转换的代码

private void ExportToShapefile(IFeatureClass fc, IWorkspace outWorkspace)
  {

   IDataset inDataSet = fc as IDataset;
   IFeatureClassName inFCName = inDataSet.FullName as IFeatureClassName;
   IWorkspace inWorkspace = inDataSet.Workspace; 
   
   IDataset outDataSet = outWorkspace as IDataset;
   IWorkspaceName outWorkspaceName = outDataSet.FullName as IWorkspaceName;
   
   IFeatureClassName outFCName = new FeatureClassNameClass();
   IDatasetName dataSetName = outFCName as IDatasetName;
   dataSetName.WorkspaceName = outWorkspaceName;
   dataSetName.Name = fc.AliasName.ToString();
   

   IFieldChecker fieldChecker = new FieldCheckerClass();
   fieldChecker.InputWorkspace = inWorkspace;
   fieldChecker.ValidateWorkspace = outWorkspace;

   IFields fields = fc.Fields;
   IFields outFields = null;
   IEnumFieldError enumFieldError = null;
   fieldChecker.Validate(fields,out enumFieldError,out outFields);
   
   IFeatureDataConverter featureDataConverter = new FeatureDataConverterClass();
   featureDataConverter.ConvertFeatureClass(inFCName,null,null,outFCName,null,outFields,"",100,0);

  }


阅读全文 | 编辑 | 删除 | 2006-3-28 13:00:32 by zhulgxg

[]

档案文件
姓名: zhulgxg
年龄:
性别:
职业:
位置: 中国

查看档案文件详细信息

以往公开日志
  • ArcEngine中对Feature的编辑 (2006-4-4)
  • ArcEngine 中ITool的使用(1) (2006-4-4)
  • ArcEngine中对象不能及时释放资源的错误 (2006-4-4)
  • ArcEngine中拓扑的使用 (2006-4-4)
  • ArcEngine中版本的使用 (2006-4-4)
  • ArcEngine中实现捕捉功能 (2006-4-3)
  • ArcEngine影像图配准 (2006-4-3)
  • ArcEngine 渲染的使用 (2006-3-29)
  • JFreeChart建立一个Chart (2006-3-28)
  • AE数据转换的代码 (2006-3-28)
  •  
    GIS论坛-GIS空间站 - GIS空间站|地理信息系统空间站


    Powered by BBSxp 5.16 SQL/Licence © 1998-2005
    Script Execution Time:62ms