ArcEngine -- 快速显示网络流向标识

本文探讨如何在ArcEngine使用C#中快速显示网络流向,提出一种方法,相比常规方式提高效率93.33倍。通过优化要素遍历、EID获取、角度计算和标识符绘制,实现了与ArcMap相似的性能。文章详细分析了优化思路并提供了优化后的代码。
摘要由CSDN通过智能技术生成

基于ArcEngine显示网络图的流向功能并不难,难的是快速显示。这节博客的内容在目前几乎所有的ArcEngine二次开发书籍中都未曾提到过,但却是一个真正成熟的商业软件开发所必需具备的。我说的快速,是比常规方法提高93.33倍的效率。

这里写图片描述

这是我的第一个有关ArcEngine开发的博客,并不是我放弃QGis了,而是现有工作环境中,还没有办法完全拥抱QGis,尤其在需要协同开发的任务上。

最近接到一个代码优化的任务,代码是基于ArcEngine使用C#二次开发的,其中有一项很主要的功能是显示网络图的流向,就像摘要里面显示的图一样。

随便上网一搜,这方面的资源也还不少,其中大家比较推崇的是一本牟乃夏老师的《ArcGIS Engine地理信息系统开发教程–基于C#.NET》书。今天我要讲的方法,在效率上比书里的代码实例要提高93.33倍左右(实测:同一台机器,同一个数据库,运行书里的代码大约需要2分20秒,本文方法只需要1.5秒)。当然这个数字并不准确,但是却说明了效率的显著提升,并且随着数据量的增大,效率提升越明显。实际上,本文的方法几乎与ArcMap中的相关功能效率一致。同时,要说明的是,牟乃夏老师的那本书很不错,值得初学者借鉴,里面很多代码可以直接使用。

定义

显示网络流向标识,首先要做的就是建立一个网络拓扑结构,这个我就不展开了,假定大家都已经正确建立了一个网络数据集。然后,就是遍历网络中的每一个线要素,判断其流向。最后,再给它赋上正确的标识符就好了。过程其实蛮简单的,关键是如何优化效率的问题。

普遍的方法

先借用牟乃夏老师书里的方法来具体说明一下实现。他的方法是

  1. 遍历网络中所有线要素
  2. 判断当前线要素的流向
  3. 根据流向类型,在屏幕适当位置画上不同的标识符。其中,画箭头标识符时还要计算线段起点与终端之间的角度。

下面是整体过程的代码,必要的地方我在注释里面说明。

/// <summary>
/// 显示流向
/// </summary>
private void showDir()
{
   try
   {
       // 得到当前几何网络所在的FeatureDataset
       IFeatureLayer featureLayer = m_layer as IFeatureLayer;
       IFeatureDataset featureDataset = featureLayer.FeatureClass.FeatureDataset;

       // 得到接口转换获得当前所加载的几何网络
       INetworkCollection2 networkCollection2 = featureDataset as INetworkCollection2;
       IGeometricNetwork geometricNetwork = networkCollection2.get_GeometricNetwork(0);

       // 获取当前的逻辑网络
       INetwork network = geometricNetwork.Network;
       IUtilityNetworkGEN utilityNetworkGEN = network as IUtilityNetworkGEN;

       // 这个是关键方法
       ShowFlowForFeatureClass(featureLayer.FeatureClass, utilityNetworkGEN);
       // 下面的这个MapControl改成你代码中的地图控件变量名称
       m_app.MapControl.ActiveView.PartialRefresh(esriViewDrawPhase.esriViewGraphics, null, m_app.MapControl.ActiveView.FullExtent);
       m_app.MapControl.Refresh();
   }
   catch 
   { 
   System.Windows.Forms.MessageBox.Show("渲染出错"); 
   return; 
   }
}

然后是 ShowFlowForFeatureClass 这个方法:

/// <summary>
/// 使用绘制的方式显示流向,速度非常慢
/// </summary>
/// <param name="featureClass">所需绘制的图层</param>
/// <param name="utilityNetworkGEN">当前几何网络对应的逻辑网络</param>
private void ShowFlowForFeatureClass(IFeatureClass featureClass, IUtilityNetworkGEN utilityNetworkGEN)
{
    // 使用INetElements接口查询网络要素的ElementID
    INetElements netElements = utilityNetworkGEN as INetElements;
    // 定义相关变量
    esriFlowDirection flowDirection = new esriFlowDirection();
    int currentEID = -1;

    // 对整个图层进行遍历,从而对每个边要素进行绘制
    IFeatureCursor featureCursor = featureClass.Search(null, false);
    int featureClassID = featureClass.FeatureClassID;

    IFeature feature = featureCursor.NextFeature();
    while (feature != null)
    {
        currentEID = netElements.GetEID(featureClassID, feature.OID, 0, esriElementType.esriETEdge);

        // 使用IUtilityNetworkGEN接口查询每个网络边要素的流向
        flowDirection = utilityNetworkGEN.GetFlowDirection(currentEID);

        // 进行绘制
        DrawArrowElementForEdgeElement(feature, m_app.MapControl.Map, flowDirection);
        feature = featureCursor.NextFeature();
    }
}

最后是 DrawArrowElementForEdgeElement 方法,以及它使用到的 GetLineAngleFrom2Points 方法:

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值