网络数据是模拟现实世界中的网络系统(如交通网、通信网、自来水管网、煤气管网等)的抽象表示。网络是由若干线性实体互连而成的一个系统,资源经由网络来传输,实体间的联络也经由网络完成。构成网络的最基本元素是上述线性实体以及这些实体的连接交汇点。
MapGIS k9提供了一个获取、存储和分析网络的完整模型,今天为大家介绍路径分析的设计与实现。
功能说明
MapGIS k9中的路径分析功能包括以下几个方面:查找路径、球最短路径、寻找最佳线路。
(1) 查找路径
查找路径即绕过障碍,在指定一系列网标之间找一条权值最小的路径。它的产生基于边线元素的顺权和逆权,节点元素的权值以及转角权值。可以根据除起始节点和终止节点外的所有中间节点的次序是否要求与输入次序一致来设置是否游历,可设定延伸角度限制和最大权值限制。它与宣召最佳路径唯一区别在于不包括对返回起点的分析。
(2) 求最短路径
求最短路径是有用户指定节点序列,求一条经过此节点序列的长度最小的路径。
(3) 寻找最佳路径
最佳路径是基础网络分析查找路径的功能扩展,除了查找路径的功能之外,还可以调整网标顺序,可以设置是否返回起点网标。
(4) 最短路径和最佳路径区别与联系
最短路径是最佳路径的特殊情况,权值设定为路径长度,所求的最佳路径即为其最短路径。此外,系统寻找最短路径时是不考虑障碍的;而找最佳路径时系统会绕过所有障碍。
实现路径分析功能调用网络分析接口INetAnalyse的PathAnalyse方法。
功能实现
1新建项目NetAnalyse。在窗体上分别绘制地图显示视图(MapGIS MapXView)、数据目录树(MapGIS mxDocTreeview)、工作空间(MapGIS MxWorkSpace)控件,并修改名称,将其连接。
2添加引用。部分引用可以直接由工作空间等三个控件调进项目中,而网络分析的动态库并没有被调入,手动添加网络分析动态库(mc_basNCls7Lib)。本实例会引用到的库有:
using mapXBase;
using mc_basXcls7Lib;
using mc_basNCls7Lib;
using mc_basObj7Lib;
3公用变了定义并初始化。
mcNetCls netCls = null; //网络类对象 IXDisplay display = null;//自定义绘图对象 mcNetFlagList NetFlagList = null;//网标对象 mcNetAnalyse NetAnalyse = null;//网络分析功能
在实现路径分析时,需要使用网标来确定地点。网标是实质是确定起始点和技术点,是通过船体显示出来,并没有真正的绘制到数据中,刷新之后可能没有显示,但是记录中确实存在数据。
4 在窗体load事件中初始化网标,并委托地图显示视图的鼠标左键单击事件:
private void Form1_Load(object sender, EventArgs e) { NetFlagList = new mcNetFlagList(); MyMapView.OnLButtonDown += new AxMapXView._IXViewEvents_OnLButtonDownEventHandler(MyMapView_OnLButtonDown); } void MyMapView_OnLButtonDown(object sender, AxMapXView._IXViewEvents_OnLButtonDownEvent e) { int ptnod=0; double pdx = 0; double pdy = 0; int plx=0; int ply=0; mcDot outdot = new mcDot (); mcPntInfo pntInfo = new mcPntInfo(); mcNetFlag netFlag = new mcNetFlag(); //点图元信息 pntInfo.symID = 34; pntInfo.width = 20; pntInfo.height = 20; pntInfo.outclr1 = 6; display = MyMapView.Display; //坐标转换:将窗口坐标转换为逻辑坐标 display.Transformation.WpToLp(e.x, e.y, ref pdx, ref pdy); mcDot dot = new mcDot(); dot.x = pdx; dot.y = pdy; //在网络类中获取指定的ID传给ptnod netCls.GetNearNod(dot, 10, out ptnod); //在网络类中获取节点ptnod的信息 netCls.GetNodPos(ptnod, out outdot); //设置网标类型为节点 netFlag.Type = meFlagType.meNodeType; //设置网标的ID为在网络类中查找的ptnod netFlag.ElemID = ptnod; //设置网标标签的值为节点的ID netFlag.Label = ptnod.ToString(); //将动态这是的点类型网标添加到网标信息列表中 NetFlagList.Add(netFlag); display.StartDraw(); display.Transformation.LpToDp(outdot.x, outdot.y, ref plx, ref ply); display.DispSubgr(plx, ply, pntInfo, 6); }
地图显示视图的单击事件主要是为了设置网标,其核心思想是,将鼠标所在位置进行捕捉,如果捕捉到网络类上的点,把他的ID记录下来,然后使用ID将捕捉到的点给网标和点对象,分别记录和绘制点:
netCls.GetNearNod(dot, 10, out ptnod);//10为捕捉半径,dot中记录了鼠标左键单击的逻辑坐标
netFlag.ElemID = ptnod; NetFlagList.Add(netFlag);//在网标中村在一个网络类上的点
5设置好网标就可以进行网络分析
private void Shortway_Click(object sender, EventArgs e) { if (NetFlagList.Count ==0) { MessageBox.Show("请先设置网标"); return; } try { //路径信息列表对象,获取路径分析结果 mcPathInfos Pathinfos = new mcPathInfos(); mcLinInfo LinInfo = new mcLinInfo(); mcDots Dots = new mcDots(); mcDots AllDots = new mcDots(); display = MyMapView.Display; NetAnalyse = new mcNetAnalyse(); bool ifCantour = false; //是否游历 bool ifCanRound = false;//是否迂回 NetAnalyse.SetNetCls(netCls); NetAnalyse.SetNetFlagList(NetFlagList); //路径分析是否游历、是否迂回分析结果 NetAnalyse.PathAnalyse(ifCantour, ifCanRound, out Pathinfos); //一闪网络分析已经结束,就是调用NetAnalyse.PathAnalyse实现分析,并将分析结果保存在了Pathinfos中,下面的功能是将分析结果显示在地图上。 for (int i = 0; i < Pathinfos.Count; i++) { Dots = NetAnalyse.GetPathGeomDot(Pathinfos.get_Item(i)); LinInfo.linstyID = 3; //LinInfo.outclr1 = 6; LinInfo.outpenw1 =40; if (Dots.count == 0) { MessageBox.Show("路径分析失败"); return; } display.StartDraw(); AllDots = display.Transformation.LpToDpArray(Dots); display.DispLine2(AllDots, LinInfo, 6); display.FinishDraw(); } } catch (Exception ex) { MessageBox.Show(ex.ToString()); } }
分析结果如下: