zoukankan      html  css  js  c++  java
  • 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新手,如有错误,希望大神们指正~

  • 相关阅读:
    数据结构之队列java版
    SPSS-相关性和回归分析(一元线性方程)案例解析(转)
    SPSS-非参数检验—两独立样本检验 案例解析(转)
    spss-非参数检验-K多个独立样本检验( Kruskal-Wallis检验)案例解析(转)
    SPSS-Friedman 秩和检验-非参数检验-K个相关样本检验 案例解析(转)
    SPSS-多重响应-频率和交叉表案例分析(问卷调查分析)(转)
    SPSS—回归—多元线性回归(转)
    SPSS—回归—曲线估计方程案例解析(转)
    SPSS—非线性回归(模型表达式)案例解析(转)
    SPSS—二元Logistic回归(转)
  • 原文地址:https://www.cnblogs.com/douzujun/p/6272667.html
Copyright © 2011-2022 走看看