QT_地图导航 源码下载

https://github.com/douzujun/MyMapView

主要算法讲解:

1. 计算最短路径(dijkstra算法)

Step1:

  (1)找到最短路径已经确定的顶点,从它已经确定的顶点,从它除法更新相邻顶点的最短距离。

  (2)此后不需要再关心1中的“最短距离已经确定的顶点”。

  (3)在(1)和(2)中提到的“最短距离已经确定的顶点”要求解的关键。在最开始时,只有起点的最短距离是确定的。而在尚未使用过的顶点中,距离d[i]最小的顶点就是最短距离已经确定的顶点。这是因为由于不存在负边,所以d[i]不会在更新中变小。

定义几个方便算法描述的变量:

  int cost[MAX_V][MAX_V]; //cost[u][v]表示表e=(u,v)的权值(不存在这条边时设为INF)

  int d[MAX_V];                 //顶点s出发的最短路径

  bool used[MAX_V];          //已经使用的图

Step2:

  (1)如果,我们需要输出最短路的路径。注,在求解最短路径时,满足d[j] = d[k] + cost[k][j]顶点k(d[j]是表示从起点开始到j的最短路径距离,cost[k][j]是表示k到j的距离),就是最短路上的顶点j的前驱结点,因此通过不断寻找前驱结点就可以恢复最短路。时间复杂度是O(E)

  (2)如果,我们用prev[j]来记录最短路上的顶点j的前驱,那么就可以在O(|V|)时间内完成最短路的恢复。在d[j]=d[k]+cost[k][j]更新时,修改prev[j]=k, 这样就可以求得prev数组。在计算从起点s出发到j的最短路时,通过prev[j]就可以知道顶点j的前驱,因此不断把j替换成prev[j]直到j = s为止即可。代码如下:

1. 首先要对图进行初始化,才能正常计算最短路径

 1 MainWindow::DijkstraFindPath::DijkstraFindPath()
 2 {
 3     mgraph.vexnum = 40;                        //初始化点数目
 4        for (int i = 0; i < mgraph.vexnum; i++) //初始化点编号
 5            mgraph.vexs.push_back (i);
 6        mgraph.arcnum = 98;                     //边数
 7        for (int i = 0; i < mgraph.vexnum; i++) {
 8            for (int j = 0; j < mgraph.vexnum; j++) {
 9                if (i == j)
10                    mgraph.arcs[i][j].adj = 0;
11                else
12                    mgraph.arcs[i][j].adj = INF;
13            }
14        }
15 }

2. 设置图的景点之间的权值。

 1 void MainWindow::DijkstraFindPath::CreateGraph ()
 2 {
 3         mgraph.arcs[0][1].adj = mgraph.arcs[1][0].adj = 45;    //6 - 5
 4         mgraph.arcs[0][6].adj = mgraph.arcs[6][0].adj = 165;   //6 - 10
 5         mgraph.arcs[1][2].adj = mgraph.arcs[2][1].adj = 45;    //5 - 4
 6         mgraph.arcs[2][3].adj = mgraph.arcs[3][2].adj = 45;    //4 - 3
 7         mgraph.arcs[3][4].adj = mgraph.arcs[4][3].adj = 45;    //3 - 2
 8         mgraph.arcs[3][15].adj = mgraph.arcs[15][3].adj = 24;  //3 - 22
 9         mgraph.arcs[4][5].adj = mgraph.arcs[5][4].adj = 45;    //2 - 1
10         mgraph.arcs[13][15].adj = mgraph.arcs[15][13].adj = 85;//23 - 22
11         mgraph.arcs[0][13].adj = mgraph.arcs[13][0].adj = 55;  //6 - 23
12         mgraph.arcs[13][2].adj = mgraph.arcs[2][13].adj = 50;  //23 - 4
13         mgraph.arcs[5][11].adj = mgraph.arcs[11][5].adj = 65;  //1 - 一食堂
14         mgraph.arcs[11][12].adj = mgraph.arcs[12][11].adj = 10;//一食堂-操场
15         mgraph.arcs[11][27].adj = mgraph.arcs[27][11].adj = 85;//一食堂-祁通1
16         mgraph.arcs[27][28].adj = mgraph.arcs[28][27].adj = 85;//祁通1-祁通2(路口)
17         mgraph.arcs[5][29].adj = mgraph.arcs[29][5].adj = 87;  //一食堂-岔路口
18         mgraph.arcs[29][11].adj = mgraph.arcs[11][29].adj = 50;//一食堂到岔路(通向7号楼的)
19         mgraph.arcs[29][30].adj = mgraph.arcs[30][29].adj = 32;//岔路-祁通大道
20         mgraph.arcs[30][10].adj = mgraph.arcs[10][30].adj = 90;//祁通大道-图书馆
21         mgraph.arcs[30][28].adj = mgraph.arcs[28][30].adj = 80;//祁通大道-祁通2
22         mgraph.arcs[28][26].adj = mgraph.arcs[26][28].adj = 15;//祁通2-方肇周
23         mgraph.arcs[25][27].adj = mgraph.arcs[27][25].adj = 273;//西大门-祁通1
24         mgraph.arcs[27][28].adj = mgraph.arcs[28][27].adj = 84; //祁通1-祁通2
25         mgraph.arcs[5][12].adj = mgraph.arcs[12][5].adj = 70;   //1 - 操场
26         mgraph.arcs[6][7].adj = mgraph.arcs[7][6].adj = 45;    //10 - 9
27         mgraph.arcs[7][8].adj = mgraph.arcs[8][7].adj = 45;    //9 - 8
28         mgraph.arcs[8][9].adj = mgraph.arcs[9][8].adj = 45;    //8 - 7
29         mgraph.arcs[9][10].adj = mgraph.arcs[10][9].adj = 150; //7 - 图书馆
30         mgraph.arcs[6][14].adj = mgraph.arcs[14][6].adj = 140; //10 - 13
31         mgraph.arcs[14][16].adj = mgraph.arcs[16][14].adj = 39;//13 - 12
32         mgraph.arcs[14][17].adj = mgraph.arcs[17][14].adj = 39;//13 - 16
33         mgraph.arcs[16][18].adj = mgraph.arcs[18][16].adj = 39;//12 - 15
34         mgraph.arcs[17][18].adj = mgraph.arcs[18][17].adj = 39;//16 - 15
35         mgraph.arcs[18][19].adj = mgraph.arcs[19][18].adj = 20;//15 - 14
36         mgraph.arcs[17][20].adj = mgraph.arcs[20][17].adj = 137;//16 - 19
37         mgraph.arcs[20][21].adj = mgraph.arcs[21][20].adj = 39; //19 - 18
38         mgraph.arcs[21][22].adj = mgraph.arcs[22][21].adj = 39; //18 - 17
39         mgraph.arcs[19][22].adj = mgraph.arcs[22][19].adj = 130;//14 - 17
40         mgraph.arcs[22][23].adj = mgraph.arcs[23][22].adj = 53; //17 - 二超
41         mgraph.arcs[23][24].adj = mgraph.arcs[24][23].adj = 5;  //二超 - 二食堂
42 
43         //以下处理细节—这是景点之间的一小段路之间的权值,因为用界面绘制路线,会//出现弧状的路线,所以需要定额外的坐标
44         mgraph.arcs[30][31].adj = mgraph.arcs[31][30].adj = 30; //祁通大道-祁通大道2
45         mgraph.arcs[31][32].adj = mgraph.arcs[32][31].adj = 10; //祁通大道2-祁通大道3
46         mgraph.arcs[32][10].adj = mgraph.arcs[10][32].adj = 20; //祁通大道3-图书馆
47         mgraph.arcs[10][33].adj = mgraph.arcs[33][10].adj = 80; //图书馆-祁通大道4
48         mgraph.arcs[33][34].adj = mgraph.arcs[34][33].adj = 45; //祁通4-祁通5
49         mgraph.arcs[34][24].adj = mgraph.arcs[24][34].adj = 45; //祁通5-二食堂
50         mgraph.arcs[34][23].adj = mgraph.arcs[23][34].adj = 45; //祁通5-二超
51         mgraph.arcs[33][35].adj = mgraph.arcs[35][33].adj = 30; //祁通4-通向14号楼的小道
52         mgraph.arcs[35][19].adj = mgraph.arcs[19][35].adj = 10; //小道-14号楼
53         mgraph.arcs[35][36].adj = mgraph.arcs[36][35].adj = 10; //小道14-小道15
54         mgraph.arcs[36][18].adj = mgraph.arcs[18][36].adj = 10; //小道15-15
55         mgraph.arcs[36][16].adj = mgraph.arcs[16][36].adj = 5;  //小道15-12
56         mgraph.arcs[37][29].adj = mgraph.arcs[29][37].adj = 40; //岔路-岔路2
57         mgraph.arcs[37][9].adj = mgraph.arcs[9][37].adj = 45;   //岔路2-7
58 
60 }

3. 计算最短路径,并对输出路径进行初始化工作。

 1 void MainWindow::DijkstraFindPath::dijkstra (int startPos)
 2 {
 3     for (int i = 0; i < mgraph.vexnum; i++) d[i] = INF;
 4     for (int i = 0; i < mgraph.vexnum; i++) used[i] = false;
 5     for (int i = 0; i < mgraph.vexnum; i++) prev[i] = -1;
 6     d[startPos] = 0;
 7 
 8     while (true) {
 9         int v = -1;
10         for (int u = 0; u < mgraph.vexnum; u++) {
11             if (!used[u] && (v == -1 || d[u] < d[v])) v = u;
12         }
13 
14         if (v == -1) break;
15         used[v] = true;
16 
17         for (int u = 0; u < mgraph.vexnum; u++) {
18             if (d[u] > d[v] + mgraph.arcs[v][u].adj) {
19                 d[u] = d[v] + mgraph.arcs[v][u].adj;
20                 prev[u] = v;
21             }
22         }
23     }
24 }

4.存储起点到终点之间的路径。

 1 QVector<int> MainWindow::DijkstraFindPath::get_Path (int endPos)
 2 {
 3     QVector<int> path;
 4 //保存景点之间的最短路径上的全部景点
 5     for ( ; endPos != -1; endPos = prev[endPos]) {
 6         path.push_back (endPos);
 7     }
 8 //由于路径是从终点向起点保存的,还需要将路径逆置。
 9     std::reverse(path.begin (), path.end ());
10     return path;
11 }

 

全部代码: 

1 首先要对图进行初始化,才能正常计算最短路径

  1 /**
  2  * 主要功能:
  3  * 1. 绘制输入起点,终点最短路径
  4  * 2. 双击地点, 查看景点信息
  5  * 3. 修改景点图片
  6  * 4. 打开测试地图,查看地图坐标,可缩放地图.
  7  **/
  8 #ifndef MAINWINDOW_H
  9 #define MAINWINDOW_H
 10 
 11 #include <QMainWindow>
 12 #include "mapwidget.h"
 13 #include <QToolButton>
 14 #include <QGraphicsLineItem>
 15 #include <QGraphicsScene>
 16 #include <QGraphicsView>
 17 #include <QLabel>
 18 #include <QComboBox>
 19 #include <QTextEdit>
 20 #include <QVector>
 21 #include <QMouseEvent>
 22 #include <QDialog>
 23 #include <QPixmap>
 24 #include <QGridLayout>
 25 #include <QLineEdit>
 26 #include <QFileDialog>
 27 #include <QHBoxLayout>
 28 
 29 class MainWindow : public QMainWindow
 30 {
 31     Q_OBJECT
 32 public:
 33     MainWindow(QWidget *parent = 0);
 34     ~MainWindow();
 35     void createToolBar();
 36     void createAction();
 37     void setStart(int X, int Y);
 38     void setEnd(int X, int Y);
 39     void setNextPos (int index);
 40     void initScene();
 41 public slots:
 42     void setStartStation();
 43     void setEndStation();
 44     void FindPath();
 45     void Clear();
 46     void Revise();
 47     void callOtherMap();
 48     void ShowDialog();
 49 private:
 50     MapWidget *mapWidget;
 51     QLabel *startLabel;
 52     QLabel *endLabel;
 53     QComboBox *startComboBox;
 54     QComboBox *endComboBox;
 55     QComboBox *reviseComboBox;
 56 
 57     QAction *findPathAction;
 58     QAction *clearAction;
 59     QAction *reviseAction;
 60     QAction *callMap;
 61 
 62     QGraphicsScene *scene;
 63     QGraphicsView *view;
 64 
 65     int startX, startY, endX, endY;
 66     QVector<int> nextPath;
 67 
 68     /*
 69      * 图的实现,和最短路径算法声明
 70      */
 71     struct ArcCell{    //弧信息
 72         int adj;       //对无权图有1,0表示是否相邻,对带权图,则为权值类型
 73     //    string info; //该弧的相关信息
 74     };
 75 
 76 
 77     //内部类
 78     static const int MAX_VERTEX_NUM = 50;
 79     static const int INF = 999999;
 80 
 81     struct MGraph{
 82         QVector<int> vexs;                                    //顶点集合
 83         //临接矩阵
 84         ArcCell arcs[MAX_VERTEX_NUM][MAX_VERTEX_NUM];
 85         int vexnum;                                           //顶点数
 86         int arcnum;                                           //边数
 87     //    int kind;                                             //图的类型
 88     };
 89 
 90     class DijkstraFindPath
 91     {
 92     public:
 93         DijkstraFindPath();
 94         MGraph mgraph;
 95         void CreateGraph();
 96 
 97         int prev[MAX_VERTEX_NUM];  //最短路上的前驱顶点
 98         int d[MAX_VERTEX_NUM];     //表示边e = (u,v)的权值(不存在时为INF,不过d[i][i]=0)
 99         bool used[MAX_VERTEX_NUM]; //已经使用过的图
100         void dijkstra(int startPos);      //求从起点startPos出发到各个顶点的最短距离
101         QVector<int> get_Path(int endPos);//到顶点endPos的最短路
102     };
103 
104     DijkstraFindPath *dj;
105 
106 //鼠标事件
107 protected:
108     void mouseDoubleClickEvent (QMouseEvent *e);
109 private:
110     QPixmap library;      //图书馆
111     QPixmap canteen;      //餐厅
112     QPixmap jxjBuilding;  //计算机楼
113     QPixmap westgate;     //西门
114     QPixmap westground;   //西操
115     QPixmap twoMarket;    //二超
116     QString strPath;      //文件路径
117     QLabel *label;
118 };
119 
120 #endif // MAINWINDOW_H
  1 #include "mainwindow.h"
  2 #include <qdebug.h>
  3 #include <QToolBar>
  4 #include <QtAlgorithms>
  5 #include <iostream>
  6 #include <windows.h>
  7 
  8 MainWindow::MainWindow(QWidget *parent)
  9     : QMainWindow(parent)
 10 {
 11     setWindowTitle ("可爱的豆豆豆 校园导航");
 12     dj = new MainWindow::DijkstraFindPath();
 13     dj->CreateGraph ();
 14 
 15     scene = new QGraphicsScene;
 16     scene->setSceneRect (-100, -100, 700, 700);
 17     initScene();
 18 
 19     view = new QGraphicsView;
 20     view->setScene (scene);
 21     view->setMinimumSize (800, 800);
 22     view->show ();
 23     setCentralWidget (view);
 24 
 25     createAction ();
 26     createToolBar ();           //实现一个工具栏
 27     setMinimumSize (800, 800);  //设置最小尺寸
 28     Sleep(2000);
 29 }
 30 
 31 MainWindow::DijkstraFindPath::DijkstraFindPath()
 32 {
 33     mgraph.vexnum = 40;                        //初始化点数目
 34        for (int i = 0; i < mgraph.vexnum; i++) //初始化点编号
 35            mgraph.vexs.push_back (i);
 36        mgraph.arcnum = 98;                     //暂定
 37        for (int i = 0; i < mgraph.vexnum; i++) {
 38            for (int j = 0; j < mgraph.vexnum; j++) {
 39                if (i == j)
 40                    mgraph.arcs[i][j].adj = 0;
 41                else
 42                    mgraph.arcs[i][j].adj = INF;
 43    //            mgraph.arcs[i][j].info = "";
 44            }
 45        }
 46 }
 47 
 48 void MainWindow::DijkstraFindPath::CreateGraph ()
 49 {
 50         mgraph.arcs[0][1].adj = mgraph.arcs[1][0].adj = 45;    //6 - 5
 51         mgraph.arcs[0][6].adj = mgraph.arcs[6][0].adj = 165;   //6 - 10
 52         mgraph.arcs[1][2].adj = mgraph.arcs[2][1].adj = 45;    //5 - 4
 53         mgraph.arcs[2][3].adj = mgraph.arcs[3][2].adj = 45;    //4 - 3
 54         mgraph.arcs[3][4].adj = mgraph.arcs[4][3].adj = 45;    //3 - 2
 55         mgraph.arcs[3][15].adj = mgraph.arcs[15][3].adj = 24;  //3 - 22
 56         mgraph.arcs[4][5].adj = mgraph.arcs[5][4].adj = 45;    //2 - 1
 57         mgraph.arcs[13][15].adj = mgraph.arcs[15][13].adj = 85;//23 - 22
 58         mgraph.arcs[0][13].adj = mgraph.arcs[13][0].adj = 55;  //6 - 23
 59         mgraph.arcs[13][2].adj = mgraph.arcs[2][13].adj = 50;  //23 - 4
 60         mgraph.arcs[5][11].adj = mgraph.arcs[11][5].adj = 65;  //1 - 一食堂
 61         mgraph.arcs[11][12].adj = mgraph.arcs[12][11].adj = 10;//一食堂-操场
 62         mgraph.arcs[11][27].adj = mgraph.arcs[27][11].adj = 85;//一食堂-祁通1
 63         mgraph.arcs[27][28].adj = mgraph.arcs[28][27].adj = 85;//祁通1-祁通2(路口)
 64         mgraph.arcs[5][29].adj = mgraph.arcs[29][5].adj = 87;  //一食堂-岔路口
 65 //        mgraph.arcs[29][9].adj = mgraph.arcs[9][29].adj = 80;  //岔路-7
 66         mgraph.arcs[29][11].adj = mgraph.arcs[11][29].adj = 50;//一食堂到岔路(通向7号楼的)
 67         mgraph.arcs[29][30].adj = mgraph.arcs[30][29].adj = 32;//岔路-祁通大道
 68         mgraph.arcs[30][10].adj = mgraph.arcs[10][30].adj = 90;//祁通大道-图书馆
 69         mgraph.arcs[30][28].adj = mgraph.arcs[28][30].adj = 80;//祁通大道-祁通2
 70         mgraph.arcs[28][26].adj = mgraph.arcs[26][28].adj = 15;//祁通2-方肇周
 71         mgraph.arcs[25][27].adj = mgraph.arcs[27][25].adj = 273;   //西大门-祁通1
 72         mgraph.arcs[27][28].adj = mgraph.arcs[28][27].adj = 84;   //祁通1-祁通2
 73         mgraph.arcs[5][12].adj = mgraph.arcs[12][5].adj = 70;  //1 - 操场
 74         mgraph.arcs[6][7].adj = mgraph.arcs[7][6].adj = 45;    //10 - 9
 75         mgraph.arcs[7][8].adj = mgraph.arcs[8][7].adj = 45;    //9 - 8
 76         mgraph.arcs[8][9].adj = mgraph.arcs[9][8].adj = 45;    //8 - 7
 77         mgraph.arcs[9][10].adj = mgraph.arcs[10][9].adj = 150; //7 - 图书馆
 78         mgraph.arcs[6][14].adj = mgraph.arcs[14][6].adj = 140; //10 - 13
 79         mgraph.arcs[14][16].adj = mgraph.arcs[16][14].adj = 39;//13 - 12
 80         mgraph.arcs[14][17].adj = mgraph.arcs[17][14].adj = 39;//13 - 16
 81         mgraph.arcs[16][18].adj = mgraph.arcs[18][16].adj = 39;//12 - 15
 82         mgraph.arcs[17][18].adj = mgraph.arcs[18][17].adj = 39;//16 - 15
 83         mgraph.arcs[18][19].adj = mgraph.arcs[19][18].adj = 20;//15 - 14
 84         mgraph.arcs[17][20].adj = mgraph.arcs[20][17].adj = 137;//16 - 19
 85         mgraph.arcs[20][21].adj = mgraph.arcs[21][20].adj = 39; //19 - 18
 86         mgraph.arcs[21][22].adj = mgraph.arcs[22][21].adj = 39; //18 - 17
 87         mgraph.arcs[19][22].adj = mgraph.arcs[22][19].adj = 130;//14 - 17
 88         mgraph.arcs[22][23].adj = mgraph.arcs[23][22].adj = 53; //17 - 二超
 89         mgraph.arcs[23][24].adj = mgraph.arcs[24][23].adj = 5;  //二超 - 二食堂
 90 //        mgraph.arcs[24][10].adj = mgraph.arcs[10][24].adj = 260;//二食堂-图书馆
 91 
 92         //以下处理细节
 93         mgraph.arcs[30][31].adj = mgraph.arcs[31][30].adj = 30; //祁通大道-祁通大道2
 94         mgraph.arcs[31][32].adj = mgraph.arcs[32][31].adj = 10; //祁通大道2-祁通大道3
 95         mgraph.arcs[32][10].adj = mgraph.arcs[10][32].adj = 20; //祁通大道3-图书馆
 96         mgraph.arcs[10][33].adj = mgraph.arcs[33][10].adj = 80; //图书馆-祁通大道4
 97         mgraph.arcs[33][34].adj = mgraph.arcs[34][33].adj = 45; //祁通4-祁通5
 98         mgraph.arcs[34][24].adj = mgraph.arcs[24][34].adj = 45; //祁通5-二食堂
 99         mgraph.arcs[34][23].adj = mgraph.arcs[23][34].adj = 45; //祁通5-二超
100         mgraph.arcs[33][35].adj = mgraph.arcs[35][33].adj = 30; //祁通4-通向14号楼的小道
101         mgraph.arcs[35][19].adj = mgraph.arcs[19][35].adj = 10; //小道-14号楼
102         mgraph.arcs[35][36].adj = mgraph.arcs[36][35].adj = 10; //小道14-小道15
103         mgraph.arcs[36][18].adj = mgraph.arcs[18][36].adj = 10; //小道15-15
104         mgraph.arcs[36][16].adj = mgraph.arcs[16][36].adj = 5;  //小道15-12
105         mgraph.arcs[37][29].adj = mgraph.arcs[29][37].adj = 40; //岔路-岔路2
106         mgraph.arcs[37][9].adj = mgraph.arcs[9][37].adj = 45;   //岔路2-7
107 
108 
109 }
110 
111 void MainWindow::DijkstraFindPath::dijkstra (int startPos)
112 {
113     for (int i = 0; i < mgraph.vexnum; i++) d[i] = INF;
114     for (int i = 0; i < mgraph.vexnum; i++) used[i] = false;
115     for (int i = 0; i < mgraph.vexnum; i++) prev[i] = -1;
116     d[startPos] = 0;
117 
118     while (true) {
119         int v = -1;
120         for (int u = 0; u < mgraph.vexnum; u++) {
121             if (!used[u] && (v == -1 || d[u] < d[v])) v = u;
122         }
123 
124         if (v == -1) break;
125         used[v] = true;
126 
127         for (int u = 0; u < mgraph.vexnum; u++) {
128             if (d[u] > d[v] + mgraph.arcs[v][u].adj) {
129                 d[u] = d[v] + mgraph.arcs[v][u].adj;
130                 prev[u] = v;
131             }
132         }
133     }
134 }
135 
136 QVector<int> MainWindow::DijkstraFindPath::get_Path (int endPos)
137 {
138     QVector<int> path;
139 
140     for ( ; endPos != -1; endPos = prev[endPos]) {
141 //        std::cout << "EndPos: " << endPos << ", ";
142         path.push_back (endPos);
143     }
144 
145     std::reverse(path.begin (), path.end ());
146 
147     return path;
148 }
149 
150 void MainWindow::initScene ()
151 {
152     QGraphicsPixmapItem *item =
153             scene->addPixmap (QPixmap("NanTong.jpg"));
154 //    item->setFlag (QGraphicsItem::ItemIsMovable);
155     item->setPos (-500, -420);
156 }
157 
158 MainWindow::~MainWindow()
159 {
160 
161 }
162 
163 void MainWindow::createAction ()
164 {
165     findPathAction = new QAction(QIcon("Search.png"),tr("搜索路径"), this);
166     findPathAction->setShortcut (tr("Ctrl+F"));
167     findPathAction->setStatusTip (tr("搜索路径"));
168     connect (findPathAction, SIGNAL(triggered(bool)), this, SLOT(FindPath()));
169 
170     clearAction = new QAction(QIcon("Clear.png"), tr("清理路径"), this);
171     clearAction->setShortcut (tr("Ctrl+W"));
172     clearAction->setStatusTip (tr("清理路径"));
173     connect (clearAction, SIGNAL(triggered(bool)), this, SLOT(Clear()));
174 
175     reviseAction = new QAction(QIcon("revise.png"), tr("修改景点"), this);
176     reviseAction->setShortcut (tr("Ctrl+R"));
177     clearAction->setStatusTip (tr("修改景点"));
178     connect (reviseAction, SIGNAL(triggered(bool)), this, SLOT(Revise()));
179 
180     callMap = new QAction(QIcon("map.png"), tr("调用测试地图"), this);
181     callMap->setShortcut (tr("Ctrl+M"));
182     callMap->setStatusTip (tr("调用测试地图"));
183     connect (callMap, SIGNAL(triggered(bool)), this, SLOT(callOtherMap()));
184 
185 }
186 
187 void MainWindow::createToolBar ()
188 {
189     QToolBar *toolBar = addToolBar ("Tool");
190     startLabel = new QLabel(tr("起点: "));
191     startComboBox = new QComboBox;
192     startComboBox->addItem (tr("公寓6号楼"));  //0
193     startComboBox->addItem (tr("公寓5号楼"));  //1
194     startComboBox->addItem (tr("公寓4号楼"));  //2
195     startComboBox->addItem (tr("公寓3号楼"));  //3
196     startComboBox->addItem (tr("公寓2号楼"));  //4
197     startComboBox->addItem (tr("公寓1号楼"));  //5
198 
199     startComboBox->addItem (tr("公寓10号楼")); //6
200     startComboBox->addItem (tr("公寓9号楼"));  //7
201     startComboBox->addItem (tr("公寓8号楼"));  //8
202     startComboBox->addItem (tr("公寓7号楼"));  //9
203     startComboBox->addItem (tr("图书馆"));     //10
204     startComboBox->addItem (tr("一食堂")); startComboBox->addItem (tr("西操场"));  //11 12
205     startComboBox->addItem (tr("公寓23号楼")); startComboBox->addItem (tr("公寓13号楼")); //13 14
206     startComboBox->addItem (tr("公寓22号楼")); startComboBox->addItem (tr("公寓12号楼")); //15 16
207     startComboBox->addItem (tr("公寓楼16")); startComboBox->addItem (tr("公寓楼15"));     //17 18
208     startComboBox->addItem (tr("公寓楼14"));  startComboBox->addItem (tr("公寓楼19"));    //19 20
209     startComboBox->addItem (tr("公寓楼18")); startComboBox->addItem (tr("公寓楼17"));     //21 22
210     startComboBox->addItem (tr("二超")); startComboBox->addItem (tr("二食堂"));           //23 24
211     startComboBox->addItem (tr("西大门")); startComboBox->addItem (tr("方肇周教学楼"));    //25 26
212 
213     endLabel = new QLabel(tr("终点: "));
214 
215     endComboBox = new QComboBox;
216     endComboBox->addItem (tr("公寓6号楼"));
217     endComboBox->addItem (tr("公寓5号楼"));
218     endComboBox->addItem (tr("公寓4号楼"));
219     endComboBox->addItem (tr("公寓3号楼"));
220     endComboBox->addItem (tr("公寓2号楼"));
221     endComboBox->addItem (tr("公寓1号楼"));
222     endComboBox->addItem (tr("公寓10号楼"));
223     endComboBox->addItem (tr("公寓9号楼"));
224     endComboBox->addItem (tr("公寓8号楼"));
225     endComboBox->addItem (tr("公寓7号楼"));
226     endComboBox->addItem (tr("图书馆"));
227     endComboBox->addItem (tr("一食堂"));    endComboBox->addItem (tr("西操场"));
228     endComboBox->addItem (tr("公寓23号楼"));endComboBox->addItem (tr("公寓13号楼"));
229     endComboBox->addItem (tr("公寓22号楼"));endComboBox->addItem (tr("公寓12号楼"));
230     endComboBox->addItem (tr("公寓楼16"));  endComboBox->addItem (tr("公寓楼15"));
231     endComboBox->addItem (tr("公寓楼14"));  endComboBox->addItem (tr("公寓楼19"));
232     endComboBox->addItem (tr("公寓楼18"));  endComboBox->addItem (tr("公寓楼17"));
233     endComboBox->addItem (tr("二超"));      endComboBox->addItem (tr("二食堂"));
234     endComboBox->addItem (tr("西大门"));    endComboBox->addItem (tr("方肇周教学楼"));
235 
236     connect (startComboBox, SIGNAL(activated(int)), this, SLOT(setStartStation()));
237     connect (endComboBox, SIGNAL(activated(int)), this, SLOT(setEndStation()));
238 
239     toolBar->addWidget (startLabel);
240     toolBar->addWidget (startComboBox);
241     toolBar->addSeparator ();
242     toolBar->addWidget (endLabel);
243     toolBar->addWidget (endComboBox);
244     toolBar->addSeparator ();
245     toolBar->addAction(findPathAction);
246     toolBar->addSeparator ();
247     toolBar->addAction(clearAction);
248     toolBar->addSeparator ();
249     toolBar->addAction(reviseAction);
250     toolBar->addSeparator ();
251     toolBar->addAction(callMap);
252 
253 }
254 
255 void MainWindow::setStart(int X, int Y) {
256     startX = X; startY = Y;
257 //    qDebug() << X << ", " << Y;
258 }
259 
260 void MainWindow::setEnd (int X, int Y)
261 {
262     endX = X; endY = Y;
263 }
264 
265 void MainWindow::setStartStation ()
266 {
267     switch (startComboBox->currentIndex ()) {
268     case 0:
269         setStart(-660, -534); break;
270     case 1:
271         setStart (-673, -490); break;
272     case 2:
273         setStart (-682, -446); break;
274     case 3:
275         setStart (-690, -400); break;
276     case 4:
277         setStart (-701, -355); break;
278     case 5:
279         setStart (-711, -310); break;
280     case 6:
281         setStart (-457, -555); break;
282     case 7:
283         setStart (-449, -485); break;
284     case 8:
285         setStart(-446, -432); break;
286     case 9:
287         setStart (-451, -400); break;
288     case 10:
289         setStart (-328, -368); break;
290     case 11:
291         setStart (-720, -247); break;
292     case 12:
293         setStart (-789, -252); break;
294     case 13:
295         setStart (-721, -517); break;
296     case 14:
297         setStart (-271, -540); break;
298     case 15:
299         setStart (-721, -439); break;
300     case 16:
301         setStart (-274, -495); break;
302     case 17:
303         setStart (-180, -552); break;
304     case 18:
305         setStart (-178, -508); break;
306     case 19:
307         setStart (-179, -456); break;
308     case 20:
309         setStart (-41, -552); break;
310     case 21:
311         setStart (-56, -500); break;
312     case 22:
313         setStart (-59, -448); break;
314     case 23:
315         setStart (-83, -393); break;
316     case 24:
317         setStart (-69, -351); break;
318     case 25:
319         setStart (-1070, -92); break;
320     case 26:
321         setStart (-438, -125); break;
322     case 27:
323         setStart (-721, -119); break;
324     case 28:
325         setStart (-550, -122); break;
326     case 29:
327         setStart (-555, -263); break;
328     case 30:
329         setStart (-498, -235); break;
330     case 31:
331         setStart (-439, -306); break;
332     case 32:
333         setStart (-390, -344); break;
334     case 33:
335         setStart (-226, -386); break;
336     case 34:
337         setStart (-144, -370); break;
338     case 35:
339         setStart (-218, -454); break;
340     case 36:
341         setStart (-223, -495); break;
342     case 37:
343         setStart (-513, -379); break;
344     default:
345         break;
346     }
347 }
348 
349 void MainWindow::setEndStation ()
350 {
351     switch (endComboBox->currentIndex ()) {
352     case 0:
353         setEnd(-660, -534); break;
354     case 1:
355         setEnd (-673, -490); break;
356     case 2:
357         setEnd (-682, -446); break;
358     case 3:
359         setEnd (-690, -400); break;
360     case 4:
361         setEnd (-701, -355); break;
362     case 5:
363         setEnd (-711, -310); break;
364     case 6:
365         setEnd (-457, -555); break;
366     case 7:
367         setEnd (-449, -485); break;
368     case 8:
369         setEnd (-446, -432); break;
370     case 9:
371         setEnd (-451, -400); break;
372     case 10:
373         setEnd (-328, -368); break;
374     case 11:
375         setEnd (-720, -247); break;
376     case 12:
377         setEnd (-789, -252); break;
378     case 13:
379         setEnd (-721, -517); break;
380     case 14:
381         setEnd (-271, -540); break;
382     case 15:
383         setEnd (-721, -439); break;
384     case 16:
385         setEnd (-274, -495); break;
386     case 17:
387         setEnd (-180, -552); break;
388     case 18:
389         setEnd (-178, -508); break;
390     case 19:
391         setEnd (-179, -456); break;
392     case 20:
393         setEnd (-41, -552); break;
394     case 21:
395         setEnd (-56, -500); break;
396     case 22:
397         setEnd (-59, -448); break;
398     case 23:
399         setEnd (-83, -393); break;
400     case 24:
401         setEnd (-69, -351); break;
402     case 25:
403         setEnd (-1070, -92); break;
404     case 26:
405         setEnd (-438, -125); break;
406     case 27:
407         setEnd (-721, -119); break;
408     case 28:
409         setEnd (-550, -122); break;
410     case 29:
411         setEnd (-555, -263); break;
412     case 30:
413         setEnd (-498, -235); break;
414     case 31:
415         setEnd (-439, -306); break;
416     case 32:
417         setEnd (-390, -344); break;
418     case 33:
419         setEnd (-226, -386); break;
420     case 34:
421         setEnd (-144, -370); break;
422     case 35:
423         setEnd (-218, -454); break;
424     case 36:
425         setEnd (-223, -495); break;
426     case 37:
427         setEnd (-513, -379); break;
428     default:
429         break;
430     }
431 }
432 
433 void MainWindow::setNextPos (int index)
434 {
435     switch (index) {
436     case 0:
437         setEnd(-660, -534); break;
438     case 1:
439         setEnd (-673, -490); break;
440     case 2:
441         setEnd (-682, -446); break;
442     case 3:
443         setEnd (-690, -400); break;
444     case 4:
445         setEnd (-701, -355); break;
446     case 5:
447         setEnd (-711, -310); break;
448     case 6:
449         setEnd (-457, -555); break;
450     case 7:
451         setEnd (-449, -485); break;
452     case 8:
453         setEnd (-446, -432); break;
454     case 9:
455         setEnd (-451, -400); break;
456     case 10:
457         setEnd (-328, -368); break;
458     case 11:
459         setEnd (-720, -247); break;
460     case 12:
461         setEnd (-789, -252); break;
462     case 13:
463         setEnd (-721, -517); break;
464     case 14:
465         setEnd (-271, -540); break;
466     case 15:
467         setEnd (-721, -439); break;
468     case 16:
469         setEnd (-274, -495); break;
470     case 17:
471         setEnd (-180, -552); break;
472     case 18:
473         setEnd (-178, -508); break;
474     case 19:
475         setEnd (-179, -456); break;
476     case 20:
477         setEnd (-41, -552); break;
478     case 21:
479         setEnd (-56, -500); break;
480     case 22:
481         setEnd (-59, -448); break;
482     case 23:
483         setEnd (-83, -393); break;
484     case 24:
485         setEnd (-69, -351); break;
486     case 25:
487         setEnd (-1070, -92); break;
488     case 26:
489         setEnd (-438, -125); break;
490     case 27:
491         setEnd (-721, -119); break;
492     case 28:
493         setEnd (-550, -122); break;
494     case 29:
495         setEnd (-555, -263); break;
496     case 30:
497         setEnd (-498, -235); break;
498     case 31:
499         setEnd (-439, -306); break;
500     case 32:
501         setEnd (-390, -344); break;
502     case 33:
503         setEnd (-226, -386); break;
504     case 34:
505         setEnd (-144, -370); break;
506     case 35:
507         setEnd (-218, -454); break;
508     case 36:
509         setEnd (-223, -495); break;
510     case 37:
511         setEnd (-513, -379); break;
512     default:
513         break;
514     }
515 }
516 
517 void MainWindow::FindPath ()
518 {
519     //Demo 在图片上绘线 在原有基础上 (+700, +440);
520     QVector<QPoint> v;
521 
522     dj->dijkstra (startComboBox->currentIndex ());
523     //设置下一处的终点
524     nextPath = dj->get_Path (endComboBox->currentIndex ());
525 
526     //准备绘制
527     Clear ();
528     //将路线绘制下来
529     QGraphicsPathItem *item = new QGraphicsPathItem();
530 
531     QPen pen;
532     pen.setWidth (4);
533     pen.setColor (Qt::red);
534     item->setPen (pen);
535     item->setFlag (QGraphicsItem::ItemIsPanel);
536 
537 //    qDebug() << startX << " " << startY << " " << endX << " " << endY;
538 
539 //    qDebug() << "Hello World !";
540 
541 
542     for (int i = 1; i < nextPath.size (); i++) {
543         qDebug() << nextPath[i] << " , ";
544     }
545     scene->addItem (item);
546 
547     QPainterPath pa;               //path
548 
549     pa.moveTo (startX + 700, startY + 440);
550 
551     //将路径用坐标存入到路径
552     for (int i = 1; i < nextPath.size() ; i++) {
553         setNextPos (nextPath[i]);
554         pa.lineTo (endX + 700, endY + 440);
555     }
556     item->setPath (pa);
557 
558 }
559 
560 void MainWindow::Clear ()
561 {
562     QList<QGraphicsItem*> listItem = scene->items ();
563     while (!listItem.empty ())
564     {
565         scene->removeItem (listItem.at (0));
566         listItem.removeAt (0);
567     }
568     QGraphicsPixmapItem *item =
569             scene->addPixmap (QPixmap("NanTong.jpg"));
570 //    item->setFlag (QGraphicsItem::ItemIsMovable);
571     item->setPos (-500, -420);
572 }
573 
574 void MainWindow::Revise ()
575 {
576     QDialog *reviseDlg = new QDialog;
577     QLabel *reviseLabel = new QLabel(tr("修改图片路径:"));
578     QLineEdit *revison = new QLineEdit(tr("\\image\\library.png"));
579     QPushButton *SureBtn = new QPushButton(tr("确定"));
580     QPushButton *CancelBtn = new QPushButton(tr("取消"));
581 
582     revison->setEnabled (false);
583 
584     reviseComboBox = new QComboBox;
585     reviseComboBox->addItem (tr("图书馆"));
586     reviseComboBox->addItem (tr("食堂"));
587     reviseComboBox->addItem (tr("西操"));
588     reviseComboBox->addItem (tr("jsj教学楼"));
589 
590     connect(reviseComboBox, SIGNAL(activated(int)), this, SLOT(ShowDialog()));
591     connect (SureBtn, SIGNAL(clicked(bool)), reviseDlg, SLOT(close()));
592     connect (CancelBtn, SIGNAL(clicked(bool)), reviseDlg, SLOT(close ()));
593 
594     revison->setText (strPath);
595 
596     QGridLayout *mainlayout = new QGridLayout(reviseDlg);
597     mainlayout->addWidget (reviseLabel, 0, 0); mainlayout->addWidget (revison, 0, 1);
598     mainlayout->addWidget (reviseComboBox, 0 , 2);
599     mainlayout->addWidget (SureBtn, 1, 1, 1, 1); mainlayout->addWidget (CancelBtn, 1, 2, 1, 1);
600 
601 
602     reviseDlg->setWindowTitle (tr("修改景点信息"));
603     reviseDlg->show ();
604 }
605 
606 void MainWindow::ShowDialog ()
607 {
608     strPath = QFileDialog::getOpenFileName (this, "打开", "/", "PNG图像(*.png)::JPEG图像(*.jpg)");
609     switch (reviseComboBox->currentIndex ()) {
610     case 0:
611         library.load (strPath); break;
612     case 1:
613         canteen.load (strPath); break;
614     case 2:
615         westground.load (strPath); break;
616     case 3:
617         jxjBuilding.load (strPath); break;
618     default:
619         break;
620     }
621 }
622 
623 //鼠标事件
624 void MainWindow::mouseDoubleClickEvent (QMouseEvent *e)
625 {
626     QDialog *dialog = new QDialog;
627     QGridLayout *layout = new QGridLayout(dialog);
628     label = new QLabel;
629 
630     qDebug() << "x : " << e->x () << ", y : " << e->y ();
631     //食堂(1060, 260)
632     if ( (e->x () >= 1060-40 && e->x () <= 1060 + 40) &&
633          (e->y () >= 260 - 10 && e->y () <= 260 + 10 ))
634     {
635         strPath = "images//canteen";
636         canteen.load (strPath);
637         label->setPixmap (canteen);
638         layout->addWidget (label);
639         dialog->setMinimumSize (1193, 274);
640         dialog->setWindowTitle ("二食堂");
641         dialog->show ();
642     }
643     else if ((e->x () >= 708-50 && e->x () <= 708 + 50) &&
644              (e->y () >= 498 - 40 && e->y () <= 498 + 40 ) ) {
645         strPath = "images//computer";
646         jxjBuilding.load (strPath);
647         label->setPixmap (jxjBuilding);
648         layout->addWidget (label);
649         dialog->setMinimumSize (437, 265);
650         dialog->setWindowTitle ("计算机楼(方肇周教学楼)");
651         dialog->show ();
652     }
653     else if ((e->x () >= 787-50 && e->x () <= 787 + 50) &&
654              (e->y () >= 287 - 50 && e->y () <= 287 + 50 ) ) {
655         strPath = "images//library";
656         library.load (strPath);
657         label->setPixmap (library);
658         layout->addWidget (label);
659         dialog->setMinimumSize (397, 340);
660         dialog->setWindowTitle ("图书馆");
661         dialog->show ();
662     }
663     else if ((e->x () >= 64-50 && e->x () <= 64 + 100) &&
664              (e->y () >= 516 - 100 && e->y () <= 516 + 100 ) ) {
665         strPath = "images//westgate";
666         westgate.load (strPath);
667         label->setPixmap (westgate);
668         layout->addWidget (label);
669         dialog->setMinimumSize (1100, 283);
670         dialog->setWindowTitle ("西大门");
671         dialog->show ();
672     }
673     else if ((e->x () >= 200-200 && e->x () <= 200 + 200) &&
674              (e->y () >= 167 - 500 && e->y () <= 167 + 500 ) ) {
675         strPath = "images//westground";
676         westground.load (strPath);
677         label->setPixmap (westground);
678         layout->addWidget (label);
679         dialog->setMinimumSize (395, 345);
680         dialog->setWindowTitle ("西操");
681         dialog->show ();
682     }
683     else if ((e->x () >= 1045 - 5 && e->x () <= 1045 + 5) &&
684              (e->y () >= 233 - 5 && e->y () <= 233 + 5 ) ) {
685         strPath = "images//twoMarket";
686         twoMarket.load (strPath);
687         label->setPixmap (twoMarket);
688         layout->addWidget (label);
689         dialog->setMinimumSize (611, 294);
690         dialog->setWindowTitle ("二超");
691         dialog->show ();
692     }
693 }
694 
695 void MainWindow::callOtherMap ()
696 {
697     mapWidget = new MapWidget;
698     mapWidget->show ();
699 }
 1 #ifndef MAPWIDGET_H
 2 #define MAPWIDGET_H
 3 
 4 #include <QGraphicsView>
 5 #include <QLabel>
 6 #include <QLineEdit>
 7 #include <QPushButton>
 8 #include <QMouseEvent>
 9 
10 class MapWidget : public QGraphicsView
11 {
12     Q_OBJECT
13 public:
14     MapWidget();
15     void readMap();                //读取地图信息
16     QPointF mapToMap(QPointF);     //用于实现场景坐标系与地图坐标间的映射.以获得某点的经纬度
17 
18 public slots:
19     void slotZoom(int);            //缩放信号
20 protected:
21     //完成地图的显示功能
22     void drawBackground (QPainter *painter, const QRectF &rect);
23 
24     void mouseMoveEvent (QMouseEvent *event);
25 private:
26     QPixmap map;
27     qreal zoom;
28     QLabel *viewCoord;  //视图目前坐标(以窗口左上为原点)
29     QLabel *sceneCoord; //场景目前坐标(以场景中心为原点)
30     QLabel *mapCoord;   //地图目前坐标
31 
32 
33     double x1, y1;
34     double x2, y2;
35 
36 };
37 
38 #endif // MAPWIDGET_H
  1 #include "mapwidget.h"
  2 #include <QSlider>         //滑动条
  3 #include <QGridLayout>
  4 #include <QFile>
  5 #include <QTextStream>
  6 #include <QGraphicsScene>
  7 #include <math.h>
  8 
  9 MapWidget::MapWidget()
 10 {
 11     //读取地图信息--用于读取描述地图信息的文件(包括地图名及经纬度等信息)
 12     readMap ();
 13     zoom = 50;
 14     int width = map.width ();
 15     int height = map.height ();
 16     //新建一个QGraphicsScene对象为主窗口连接一个场景
 17     QGraphicsScene *scene = new QGraphicsScene(this);
 18     //限定场景的显示区域为地图大小
 19     scene->setSceneRect (-width/2, -height/2, width, height);
 20     setScene (scene);
 21     /***
 22      * The background is cached(隐藏,缓存). This affects both custom backgrounds, and
 23      * backgrounds based on the backgroundBrush property. When this flag is enabled,
 24      * QGraphicsView will allocate one pixmap with the full size of the viewport
 25      */
 26     setCacheMode (CacheBackground);
 27     /***
 28      * 用于地图缩放的滑动条
 29      * 新建一个QSlider对象作为地图的缩放控制
 30      */
 31     QSlider *slider = new QSlider;
 32     //设置滚动条方向-垂直
 33     slider->setOrientation (Qt::Vertical);
 34     slider->setRange (1, 100);        //设置地图缩放比例值范围为0~100
 35     slider->setTickInterval (10);     //显示刻度间隔为10
 36     slider->setValue (0);            //设置当前初始值为50
 37     // 将缩放控制条的valueChanged()信号与地图缩放slotZoom()槽函数相关联
 38     connect (slider, SIGNAL(valueChanged(int)), this, SLOT(slotZoom(int)));
 39 
 40     //缩放图标
 41     QLabel *zoominLabel = new QLabel;
 42     zoominLabel->setScaledContents (true);
 43     zoominLabel->setPixmap (QPixmap("zoomin.png"));
 44     QLabel *zoomoutLabel = new QLabel;
 45     zoomoutLabel->setScaledContents (true);
 46     zoomoutLabel->setPixmap (QPixmap("zoomout.png"));
 47 
 48     //坐标值显示区
 49     QLabel *label1 = new QLabel(tr("GraphicsView:"));
 50     viewCoord = new QLabel;
 51     QLabel *label2 = new QLabel(tr("GraphicsScene:"));
 52     sceneCoord = new QLabel;
 53     QLabel *label3 = new QLabel(tr("map:"));
 54     mapCoord = new QLabel;
 55 
 56     //坐标显示区布局
 57     QGridLayout *gridLayout = new QGridLayout;
 58     gridLayout->addWidget (label1, 0, 0);
 59     gridLayout->addWidget (viewCoord, 0, 1);
 60 
 61     gridLayout->addWidget (label2, 1, 0);
 62     gridLayout->addWidget (sceneCoord, 1, 1);
 63 
 64     gridLayout->addWidget (label3, 2, 0);
 65     gridLayout->addWidget (mapCoord, 2, 1);
 66 
 67     gridLayout->setSizeConstraint (QLayout::SetFixedSize);
 68     QFrame *coordFrame = new QFrame;
 69     coordFrame->setLayout (gridLayout);
 70 
 71     //缩放控制子布局
 72     QVBoxLayout *zoomLayout = new QVBoxLayout;
 73     zoomLayout->addWidget (zoominLabel);
 74     zoomLayout->addWidget (slider);
 75     zoomLayout->addWidget (zoomoutLabel);
 76 
 77     //坐标显示区布局
 78     QVBoxLayout *coordLayout = new QVBoxLayout;
 79     coordLayout->addWidget (coordFrame);
 80     coordLayout->addStretch ();
 81     //主布局
 82     QHBoxLayout *mainLayout = new QHBoxLayout;
 83     mainLayout->addLayout (zoomLayout);
 84     mainLayout->addLayout (coordLayout);
 85     mainLayout->addStretch ();          //平均分割
 86     mainLayout->setMargin (30);         //设置对话框(或窗体)的边距为30
 87     mainLayout->setSpacing (10);        //设定各个控件之间的间距为10
 88     setLayout (mainLayout);             //在场景中设置为布局
 89 
 90     setWindowTitle ("Map Widget");
 91     setMinimumSize (600, 400);
 92 }
 93 
 94 //读取地图信息
 95 void MapWidget::readMap ()
 96 {
 97     QString mapName;
 98     //新建一个QFile对象,“map.txt"是描述地图信息的文本文件
 99     QFile mapFile("maps.txt");
100     //以"只读"的方式打开此文件
101     int ok = mapFile.open (QIODevice::ReadOnly);
102     if (ok)                   //分别以读取地图的名称和四个经纬度信息
103     {
104         QTextStream ts(&mapFile);
105         if (!ts.atEnd ()) {              //没有到末尾返回false
106             ts >> mapName;               //储存字符串
107             ts >> x1 >> y1 >> x2 >> y2;  //储存地图左上角和右下角的经纬度
108         }
109     }
110     map.load (mapName);      //将地图读取至私有标量map中
111 }
112 
113 //根据缩放滑动条的当前值,确定缩放的比例,调用scale()函数实现地图缩放--完成地图缩放功能slotZoom
114 void MapWidget::slotZoom (int value)
115 {
116     qreal s;                  //缩放大小
117     if (value > zoom) {       //放大
118         s = pow (1.01, (value - zoom));
119     }
120     else {
121         s = pow(1/1.01, (zoom - value));
122     }
123     scale(s, s);
124     zoom = value;            //当前放大值
125 }
126 
127 //drawBackground()--以地图图片重绘场景的背景来实现地图显示
128 void MapWidget::drawBackground (QPainter *painter, const QRectF &rect)
129 {
130     /***
131      * The scene rectangle defines the extent of the scene, and in the view's case,
132      * this means the area of the scene that you can navigate using the scroll bars.
133      */
134     painter->drawPixmap (int(sceneRect ().left ()) + 10, int(sceneRect ().top ()) - 10, map);
135 
136 }
137 
138 //完成某点在各层坐标中的映射及显示
139 void MapWidget::mouseMoveEvent (QMouseEvent *event)
140 {
141     //QGraphicesView 坐标
142     QPoint viewPoint = event->pos ();   //鼠标事件位置
143     viewCoord->setText (QString::number (viewPoint.x ()) + "," + QString::number (viewPoint.y ()));
144 
145     //QGraphiccsScene 坐标 -- 将视图坐标转换成场景坐标
146     QPointF scenePoint = mapToScene (viewPoint);
147     sceneCoord->setText (QString::number (scenePoint.x ()) + "," + QString::number (scenePoint.y ()));
148 
149     //地图坐标(经,纬度值)
150     QPointF latLon = mapToMap (scenePoint);
151     mapCoord->setText (QString::number (latLon.x ()) + "," + QString::number (latLon.y ()));
152 
153 
154 }
155 
156 //完成从场景至地图坐标的转换mapToMap()
157 QPointF MapWidget::mapToMap (QPointF p)
158 {
159     QPointF latLon;       //地图坐标
160     qreal w = sceneRect ().width ();      //场景长度
161     qreal h = sceneRect ().height ();     //场景高度
162     qreal lon = y1 - ( (h/2+p.y ()) * abs(y1-y2)/h );
163     qreal lat = x1 + ( (w/2+p.x ()) * abs(x1-x2)/w );
164 
165     latLon.setX (lat);
166     latLon.setY (lon);
167     return latLon;
168 }
 1 #include "mainwindow.h"
 2 #include "mapwidget.h"
 3 #include <QApplication>
 4 #include <QFont>
 5 #include <QDebug>
 6 #include <QPixmap>
 7 #include <QSplashScreen>
 8 
 9 int main(int argc, char *argv[])
10 {
11     QApplication a(argc, argv);
12     QPixmap pixmap("312");        //创建QPixmap对象,设置启动图片
13     QSplashScreen splash(pixmap); //利用QPixmap对象创建一个QSplashScreen对象
14     splash.show ();               //显示此启动图片
15 
16     a.processEvents ();           //使程序在显示启动动画的同时能能响应鼠标等其他事件
17 
18     QFont font("ARPL KaitiM GB", 12);
19     font.setBold (true);
20     a.setFont (font);
21 
22     qDebug() << "Run............";
23     MainWindow w;
24     w.show ();
25 
26     //表示在主窗体对象初始化完成后,结束启动画面
27     splash.finish (&w);
28 
29 
30     return a.exec();
31 }

 源码下载: http://pan.baidu.com/s/1boEzMJt

 qt新手,如有错误,希望大神们指正~

posted @ 2017-01-11 10:41  douzujun  阅读(9672)  评论(0编辑  收藏  举报