• 基于SuperMap iObjects C++之最佳路径分析


            最佳路径分析是交通网络分析中最常用的一种分析功能。功能实现的是找出网络中两点之间阻力最小的路径,如果是对多个结点进行最佳路径分析,必须按照结点的选择顺序依次访问。阻力最小有多种含义,如基于单因素考虑的时间最短、费用最低、路况最佳、收费站最少等,或者基于多因素综合考虑的、路况最好且收费站最少等。

            那么在SuperMap中,我们怎么来实现最佳路径分析呢?下面就跟着小编来一起看一看吧。

    我们需要做什么准备?

            首先,我们要理解在地理信息世界中,公共基础设施(电力设施、电信与有线电视网络、道路交通、水网等)被抽象为“网络系统”。网络系统是指有许多相互连接的线段构成的网状系统,网络模型是对现实世界中网络系统的抽象表达。例如在城市交通网中,道路等线状地物被抽象为线段,在网络中称为网络弧段;而十字路口、公交站点等点状地物被抽象为点,在网络中称为网络结点。在网络模型中,资源和信息能够沿着弧段,从一个结点到达另外一个结点。可以这么理解,网络就是边(线)和交汇点(结点)等元素共同组成的,表示了从一个位置到另外一个位置的可能路径。

    我们必须要理解的基本概念

            网络是由一组相互关联弧段、结点和它们的属性所组成的模型。网络用于表达现实世界中的道路、管线等。

            如上图所示,网络不仅具有一般网络的弧段与结点间的抽象拓扑关系,还具有 GIS 空间数据的几何定位特征和地理属性特征(拓扑关系时地理对象在空间位置上的相互关系,如结点与线、线与面之间的连接关系)。

    结点

            结点是网络中弧段相连接的地方,如上图所示。结点可以表示现实中的道路交叉口、河流交汇点等点要素。结点和弧段各自对应一个属性表,它们的邻接关系通过属性表的字段来关联。

    弧段

            弧段就是网络中的一条边,弧段通过结点和其它的弧段相连接。弧段可用于表示现实世界运输网络中的高速路、铁路、电网中的传输线和水文网络中的河流等。弧段之间的相互联系是具有拓扑结构的。

    网络阻力

            现实生活中,从起点出发,经过一系列的道路和路口抵达目的地,必然会产生一定的花费。这个花费可以用距离、时间、货币等度量。在网络模型中,把通过结点或弧段的花费抽象成网络阻力,并将该信息存储在属性字段中,称为阻力字段。

    障碍边和障碍点 

            城市中的交通堵塞问题随处可见,交通拥堵是没有规律可循、随机且动态变化的过程。为了实时地反映交通网络的现状,需要让交通堵塞的弧段具有暂时禁止通行的特性,同时在交通恢复正常后,弧段属性也能实时恢复正常。障碍边、障碍点概念的提出可以很好地解决上述问题。障碍边、障碍点引入的好处是障碍设置与否与现有的网络环境参数无关,具有相对独立的特性。

            理解了关于网络数据集以及网络数据集相关的一些基本概念,我们就需要提前先来准备一套网络数据集。网络数据集怎么制作,可以参考之前的博客:https://blog.csdn.net/supermapsupport/article/details/100132171

            注意:这里可能有人会有疑问,为什么明明是基于SuperMap C++实现最佳路径分析,但是上面博客中制作网络数据集的内容却是关于在iDesktop中构建网络数据集,这里统一解释一下,由于前期的数据处理,可能不仅仅涉及到构建网络数据集,包括数据导入、数据拓扑检查,对象属性修改编辑等等操作,如果所有操作都在组件开发层面去实现,会有一定的难度,而且没有必要,所以我们通常都是使用SuperMap提供的专门用于前期处理数据的iDesktop软件工作进行数据的入库,处理。使用其他功能的时候也是同样的道理,会先在桌面软件中,将数据制作完成,地图配图,保存为工作空间文件(*.smwu),组件开发直接打开数据即可,程序开发只实现业务需求。

    关于如何打开数据,这里可以参考之前的博客:

    环境配置(windows环境VS + Qt):SuperMap iObjects for C++ 入门详解(VS + Qt)_supermapsupport的博客-CSDN博客

    环境配置(windows+MFC):SuperMap iObjects C++之MFC快速入门_supermapsupport的博客-CSDN博客_sumpermap c++配置

    环境配置(Qt Creator):https://blog.csdn.net/supermapsupport/article/details/52609945

    数据源管理:SuperMap iObjects C++之数据源管理_supermapsupport的博客-CSDN博客_supermap怎么打开udb数据源

            好啦,到这里,我就假装你们都已经准备好了所需的网络数据集,接来下就看看具体的最佳路径在代码逻辑上是如何实现的吧。

    下面以一个简单的代码例子来进行说明:

    1. 首先,从数据源里面拿到网络数据集,网络数据集的对象类型也是矢量数据集UGDatasetVector。
    2. 确定参加分析的站点,可以是两个点,也可以是多个点。数量大于等于2。
    3. 确定耗费字段,如果有其他耗费字段,可以自行新建一个字段,并且将对应的耗费值设置到网络弧段数据属性表里面,如果是直接根据距离来进行分析,可以直接使用系统字段smlength。

    最佳路径分析的关键类:

    UGNetworkAnalyst:网络分析基类,主要用于构造一个网络分析环境,设置用于参加分析的网络数据集,弧段标识字段、弧段起始结点 ID 的字段,容限等等环境参数;

    UGPathAnalyst:交通网络分析类。 该类用于提供路径分析、旅行商分析、服务区分析、多旅行商(物流配送)分析、最近设施查找和选址分区分析等交通网络分析的功能。

    UGAnalyseParams:交通网络参数及结果类,设置权重字段,以及返回结果类型等等参数。

    最佳分析关键代码如下:

    传入的参数:

    netDataset:上面第一点所说的网络数据集;

    Points:参加分析的点串数据;

    costFiled:耗费字段,这里直接添加字段名称即可。

    最后的返回值:就是最佳路径的线对象。

    具体实现代码参考:

    1. UGGeoLine* MMapControl::FindPathByNetWork(UGDatasetVector* netDataset, UGPoint2Ds Points,UGString costFiled)
    2. {
    3.     try {
    4.         UGGeoLine* geoline_result = new UGGeoLine();
    5.         //构造一个最佳路径分析环境设置对象
    6.         UGNetworkAnalyst* pUGTrafficAnalyst = new UGNetworkAnalyst();
    7.         //构造一个最佳路径分析对象
    8.         UGPathAnalyst* pUGPathAnalyst = new UGPathAnalyst(pUGTrafficAnalyst);
    9.         //权重字段信息
    10.         UGCostFields CostFiled;
    11.         UGArray<UGCostFields> strCostFiledName;
    12.         strCostFiledName.SetSize(1);
    13.         CostFiled.strCostName = costFiled;
    14.         CostFiled.strFTField = costFiled;
    15.         CostFiled.strTFField = costFiled;
    16.         strCostFiledName.SetAt(0, CostFiled);
    17.         //设置网络数据集
    18.         pUGTrafficAnalyst->SetDatasetNetwork(netDataset);
    19.         //设置网络数据集中标志结点ID的字段
    20.         pUGTrafficAnalyst->SetNodeIDField(_U("SmNodeID"));
    21.         //设置网络数据集中标志弧段 ID 的字段
    22.         pUGTrafficAnalyst->SetArcIDField(_U("SmEdgeID"));
    23.         //设置网络数据集中标识弧段起始结点 ID 的字段
    24.         pUGTrafficAnalyst->SetFNodeIDField(_U("SmFNode"));
    25.         //设置网络数据集中标志弧段终止结点 ID 的字段
    26.         pUGTrafficAnalyst->SetTNodeIDField(_U("SmTNode"));
    27.         //设置点到弧段的距离容限
    28.         pUGTrafficAnalyst->SetNodeInterval(50);
    29.         //设置一个阻力别名为耗费
    30.         pUGTrafficAnalyst->SetCostFields(strCostFiledName);
    31.         //创建邻接矩阵
    32.         pUGTrafficAnalyst->DeleteAdjMatrix();
    33.         if (!pUGTrafficAnalyst->CreateAdjMatrix())
    34.         {
    35.             //TRACE("创建邻接矩阵失败");
    36.             return NULL;
    37.         }
    38.         //TRACE("创建邻接矩阵成功");
    39.         //参数设置
    40.         UGAnalyseParams AnalyseParams;
    41.         //设置权值字段
    42.         UGString strCostName = pUGTrafficAnalyst->GetFirstCostName();
    43.         AnalyseParams.strCostName = strCostName;
    44.         //设置结果结构,返回路由及途径节点
    45.         AnalyseParams.nOptions = -1;
    46.         //设置分析点
    47.         AnalyseParams.arrViaPoints = Points;
    48.         //结果信息存储
    49.         UGResultInfo ResInfoOut;
    50.         ResInfoOut.Clear();
    51.         //最佳路径分析
    52.         if (!pUGPathAnalyst->FindPath(AnalyseParams, ResInfoOut, false))
    53.         {
    54.             //TRACE("最佳路径分析失败");
    55.             return NULL;
    56.         }
    57.         //TRACE("最佳路径分析成功");
    58.         UGArray<UGGeoLineM> arrLineM = ResInfoOut.arrLineM;
    59.         //UGGeoLine geoline;
    60.         UGGeoLineM lineM = arrLineM.GetAt(0);
    61.         lineM.ConvertToLine(*geoline_result, 10);
    62.         return geoline_result;
    63.     } catch (double d) {
    64.         //return NULL;
    65.     }
    66. }

    分析结果:

    拿到结果的geoline后,我们可以将结果对象添加到跟踪图层进行临时展示。

    注意:

    1. 站点必须位于网络弧段和网络结点上,或者在设定的容限范围的区域。可以在“分析环境”窗口中,对结点捕捉容限进行设置,修改合适的容限大小。
    2. 如果存在障碍点,可以在分析的时候,设置障碍点参数AnalyseParams.arrBarrierNodeID。
    3. 如果存在障碍边,也就是有一条弧段数据是不通的情况下,就可以将这条弧段设置为障碍边,分析的时候,设置障碍边参数AnalyseParams.arrBarrierArcID。

  • 相关阅读:
    【Linux】《Linux命令行与shell脚本编程大全 (第4版) 》笔记-ChapterA-bash 命令快速指南
    vue-cli3 vue项目 动态修改favicon.ico(浏览器顶部小图标)
    No spring.config.import property has been defined
    LabVIEW开发低成本静脉监测和控制输液系统
    链表试题(Python实现)
    (三) CPU 性能测试 (CPU负载高对应的不同情况)
    ChatGPT研究论文提示词集合1-【主题选择与问题研究、文献综述】
    vuex中的 actions 中,是不能使用 this.$message.error() 的
    Unity WebGL 播放视频流m3u8
    day08-XML
  • 原文地址:https://blog.csdn.net/supermapsupport/article/details/127749617