你好,欢迎来到电脑编程技巧与维护杂志社! 杂志社简介广告服务读者反馈编程社区  
合订本订阅
 
 
您的位置:杂志经典 / 图形图象处理与游戏编程
5.1 中国主干公路网最短路径查询(上)
 

一、MapX简介

 

MapX控件是由MapInfo公司提供的具有强大地图分析功能的ActiveX控件产品。由于它是一种基于Windows操作系统的标准控件,因而能支持大多数标准的可视化开发环境,如Visual BasicVisual C++DelphiPowerBuilder等。通过MapX控件可以将地图功能嵌入到应用程序中,并可脱离MapInfo的软件平台运行。MapX控件按图层组织地图,每个图层包含整个地图的一个方面并对应一个MapInfo表。文中的中国主干公路网由“中国主干公路节点”图层和“中国主干公路线”图层组成,数据为MapInfo格式。中国主干公路节点.tab和中国主干公路线.tab数据组织格式如图1和图2所示。


1 中国主干公路节点.tab


2 中国主干公路线.tab

二、Dijkstra算法

    Dijkstra算法是目前公认的效率较高的最短路径算法。算法基本思想是采用标号的方法,从起点开始逐步向外搜索起点到其他各点的最短路径。算法基本步骤如下:

首先给起始节点标上永久性标号0,然后给每个与起始节点直接相连的节点标上一个临时标号,标号值为连接起始节点和该节点线路的长度值。给其他未与起始节点直接相连的节点的临时标号为

选择具有最小临时标号的节点,将该节点的临时标号改为永久性标号。假设节点 是刚获得永久性标号的节点,搜索每个与节点 直接相连且具有临时标号的节点 ,用min{节点 目前的临时标号,节点 的永久性标号+线路 的长度值}对节点 的临时标号进行更新。

重复以上步骤,直到所有节点都具有永久性标号。此时的每个永久性标号值,代表起始节点到该节点的最短距离。如果只要求起点到指定终点的最短距离,则在指定终点获得永久性标号时即可停止标号过程。

要求出起点到终点的最短路径,需要从终点逆推,求出永久标号差值正好等于线路长度的节点以下为算法示例。    

在图3中,查询从节点1到节点6的最短路径的标号过程如下:(*表示永久性标号)


3 算法示例


所以节点1到节点6的最短距离为8,进行逆推求最短路径。节点6和节点5之间的永久标号之差是8-6=线路(56)的长度,所以可以回到节点5。节点5和节点2之间的永久标号之差是6-4=线路(25)的长度,回到节点2。节点2和节点1的永久标号之差4=线路(12)的长度,回到起点1,得到最短路径1-2-5-6。在节点5时,还可以回到节点3得到最短路径1-3-5-6

三、程序实现

VB中引用MapX控件的步骤为:工程→部件→控件→MapInfo MapX V5。在窗口中加入MapX控件,添加菜单、工具栏、文本框等,程序界面如图4所示。在MapX控件中添加“中国主干公路节点”和“中国主干公路线”图层步骤为:在MapX控件上点右键→特性→LayersAdd,选中要添加的图层即可,实现的核心代码如下:


4 程序界面

Option Base 1

Const select_point As Integer = 1

Dim nodelayerindex As Integer, linelayerindex As Integer

Dim LatNode() As Double, LonNode() As

Double, NoNode() As Integer, nNode As

Integer  '节点的纬度、经度、标注、节点数

Dim LineNode() As Integer, LineDis() As

Double, nLineNode As Integer  

'线路的端点(redim成二维的)、长度、

'线路数

Dim StartNo As Integer, EndNo As Integer    '查询时指定的起点、终点

Dim flagMatrix() As Boolean, distmatrix() As

Double  '标记节点是否邻接、邻接距离

Dim yjdb() As Boolean, distvector() As

Double 

'标记节点是否获得永久标号、与起点的距离

Dim tempstartno As Integer, tempendno As

Integer, oldtempstartno As Integer

Dim isall As Boolean  

'标记是否所有节点都获得永久标号

Dim szdno() As Integer '最短路径上的节点

Dim shortestdist As Double  '最短距离

Private Sub Form_Load() '初始化,读取数据

Map1.CreateCustomTool select_point,

miToolTypePoint, miCenterCursor

 '创建用户自定义点选择工具,

'用于指定起点、终点

Dim lyr As MapXLib.Layer

Dim nodelyr As MapXLib.Layer, nodeds As

MapXLib.Dataset

Dim ftr As MapXLib.Feature

Dim i As Integer, j As Integer, k As Integer,

temp As Integer, q As Integer, maxlen As

Double

For Each lyr In Map1.Layers  '添加数据集

Map1.DataSets.Add miDataSetLayer, lyr,

lyr.Name & "dataset"

Next

For i = 1 To Map1.Layers.Count

  If Map1.Layers(i).Name = "中国主干公路节点" Then

    nodelayerindex = i '公路节点图层编号

  End If 

  If Map1.Layers(i).Name = "中国主干公路线" Then

    linelayerindex = i '线路图层编号

  End If

Next i

Set nodelyr = Map1.Layers(nodelayerindex)

nodelyr.AutoLabel = True

Set nodeds = Map1.DataSets.

Add(miDataSetLayer, nodelyr)

Set nodelyr.LabelProperties.Dataset = nodeds

Set nodelyr.LabelProperties.DataField =

nodeds.Fields(3)

nodelyr.LabelProperties.Position =

miPositionCR

nodelyr.LabelProperties.Visible = True

nNode = 0: nLineNode = 0

For Each ftr In

Map1.Layers(nodelayerindex).AllFeatures

   nNode = nNode + 1 '节点数

Next

For Each ftr In

Map1.Layers(linelayerindex).AllFeatures

   nLineNode = nLineNode + 1 '线路数

Next

ReDim LonNode(1 To nNode) As Double,

LatNode(1 To nNode) As Double, NoNode(1

To nNode) As Integer  '节点初始化

ReDim LineNode(1 To 2, 1 To nLineNode),

LineDis(1 To nLineNode)   '线路初始化

For i = 1 To nNode

   LatNode(i) =

Map1.DataSets(nodelayerindex).Value(i, 1) 

'公路节点的纬度

   LonNode(i) =

Map1.DataSets(nodelayerindex).Value(i, 2) 

'经度

   NoNode(i) =

Map1.DataSets(nodelayerindex).Value(i, 3)

'标注

Next i

For i = 1 To nLineNode

  LineNode(1, i) =

Map1.DataSets(linelayerindex).Value(i, 1) 

'线路的第1个节点

  LineNode(2, i) =

Map1.DataSets(linelayerindex).Value(i, 2) 

'线路的第2个节点

  LineDis(i) =

Map1.DataSets(linelayerindex).Value(i, 3)

'线路长度

Next i

ReDim flagMatrix(1 To nNode, 1 To nNode)

As Boolean

ReDim distmatrix(1 To nNode, 1 To nNode)

As Double

For i = 1 To nNode 

'flagMatrix标记节点是否邻接

    For j = 1 To nNode   '初始化

  推荐精品文章

·2024年9月目录 
·2024年8月目录 
·2024年7月目录 
·2024年6月目录 
·2024年5月目录 
·2024年4月目录 
·2024年3月目录 
·2024年2月目录 
·2024年1月目录
·2023年12月目录
·2023年11月目录
·2023年10月目录
·2023年9月目录 
·2023年8月目录 

  联系方式
TEL:010-82561037
Fax: 010-82561614
QQ: 100164630
Mail:gaojian@comprg.com.cn

  友情链接
 
Copyright 2001-2010, www.comprg.com.cn, All Rights Reserved
京ICP备14022230号-1,电话/传真:010-82561037 82561614 ,Mail:gaojian@comprg.com.cn
地址:北京市海淀区远大路20号宝蓝大厦E座704,邮编:100089