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

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

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

我们需要做什么准备?

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

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

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

基于SuperMap iObjects C++之最佳路径分析_第1张图片

        如上图所示,网络不仅具有一般网络的弧段与结点间的抽象拓扑关系,还具有 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:耗费字段,这里直接添加字段名称即可。

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

具体实现代码参考:

UGGeoLine* MMapControl::FindPathByNetWork(UGDatasetVector* netDataset, UGPoint2Ds Points,UGString costFiled)

{

    try {

        UGGeoLine* geoline_result = new UGGeoLine();



        //构造一个最佳路径分析环境设置对象

        UGNetworkAnalyst* pUGTrafficAnalyst = new UGNetworkAnalyst();

        //构造一个最佳路径分析对象

        UGPathAnalyst* pUGPathAnalyst = new UGPathAnalyst(pUGTrafficAnalyst);

        //权重字段信息

        UGCostFields CostFiled;

        UGArray strCostFiledName;

        strCostFiledName.SetSize(1);

        CostFiled.strCostName = costFiled;

        CostFiled.strFTField = costFiled;

        CostFiled.strTFField = costFiled;

        strCostFiledName.SetAt(0, CostFiled);



        //设置网络数据集

        pUGTrafficAnalyst->SetDatasetNetwork(netDataset);

        //设置网络数据集中标志结点ID的字段

        pUGTrafficAnalyst->SetNodeIDField(_U("SmNodeID"));

        //设置网络数据集中标志弧段 ID 的字段

        pUGTrafficAnalyst->SetArcIDField(_U("SmEdgeID"));

        //设置网络数据集中标识弧段起始结点 ID 的字段

        pUGTrafficAnalyst->SetFNodeIDField(_U("SmFNode"));

        //设置网络数据集中标志弧段终止结点 ID 的字段

        pUGTrafficAnalyst->SetTNodeIDField(_U("SmTNode"));

        //设置点到弧段的距离容限

        pUGTrafficAnalyst->SetNodeInterval(50);

        //设置一个阻力别名为耗费

        pUGTrafficAnalyst->SetCostFields(strCostFiledName);

        //创建邻接矩阵

        pUGTrafficAnalyst->DeleteAdjMatrix();

        if (!pUGTrafficAnalyst->CreateAdjMatrix())

        {

            //TRACE("创建邻接矩阵失败");

            return NULL;

        }

        //TRACE("创建邻接矩阵成功");

        //参数设置

        UGAnalyseParams AnalyseParams;

        //设置权值字段

        UGString strCostName = pUGTrafficAnalyst->GetFirstCostName();

        AnalyseParams.strCostName = strCostName;

        //设置结果结构,返回路由及途径节点

        AnalyseParams.nOptions = -1;

        //设置分析点



        AnalyseParams.arrViaPoints = Points;

        //结果信息存储

        UGResultInfo ResInfoOut;

        ResInfoOut.Clear();

        //最佳路径分析

        if (!pUGPathAnalyst->FindPath(AnalyseParams, ResInfoOut, false))

        {

            //TRACE("最佳路径分析失败");

            return NULL;

        }

        //TRACE("最佳路径分析成功");

        UGArray arrLineM = ResInfoOut.arrLineM;



        //UGGeoLine geoline;

        UGGeoLineM lineM = arrLineM.GetAt(0);

        lineM.ConvertToLine(*geoline_result, 10);

        return geoline_result;



    } catch (double d) {

        //return NULL;

    }

}

分析结果:

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

基于SuperMap iObjects C++之最佳路径分析_第2张图片

注意:

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

你可能感兴趣的:(组件GIS,c++,开发语言)