• QT、C++实现地图导航系统(mapSystem)


    地图导航系统

    项目应用背景

    电子地图导航系统的主要目的是为用户提供精确、实时的导航和位置信息,以帮助他们在城市或地区内轻松找到目的地。
    ①提供用户友好的界面,使用户能够轻松输入起点和目的地,并获取最佳的导航路线。
    ②支持用户个性化设置,例如选择不同的地图样式、导航偏好和关注的兴趣点,以满足不同用户的需求。
    ③提供可靠的地图数据,包括道路、建筑物、公共设施和兴趣点的详细信息,以帮助用户更好地理解其周围环境。
    在这里插入图片描述

    技术栈选择

    用哈希map以及设置类进行数据的存储

    对于地图导航系统,我们需要考虑到数据的存储防止内存的溢出,地图中的数据多并且杂需要进行数据清洗。对于我们需要的数据提取出来并存储下来。这样我们需要考虑数据的存储方式而且需要在数据调用时可以更快的将某条数据进行处理。

    Floyd路径算法计算最短路径

    考虑到该算法可以实现全局最短路径的搜索;既适用于有向图又适用于无向图;采用动态规划思想,通过逐步优化子问题的解决方案来找到整体的最优解;适用性广泛, Floyd算法适用于各种类型的图,包括稠密图和稀疏图,它不依赖于特定的图结构,因此可以用于多种应用领域。

    QT实现图形界面开发

    QT的图形界面实现简单容易;模块化,可扩展,QT的模块化架构允许你仅包含你需要的模块,从而减小应用程序的大小。

    数据处理

    Openstreetmap 数据osm数据的格式的特点,虽然是osm数据格式但是获取的数据格式xml可以通过解析xml数据格式的方式进行解析。
    数据解析: 使用QT中的xml解析库函数进行数据的解析。读取其中的数据挑选出其中的ID 号,Lat维度,Lon经度。

    算法实现

    真实经纬度坐标结构体类型
    在这里插入图片描述

    经纬度坐标转换函数
    在这里插入图片描述

    构造解析OSM(XMl)类
    在这里插入图片描述

    数据类型转化
    在这里插入图片描述
    根据经纬度计算点与点之间距离
    在这里插入图片描述
    画出道路图
    在这里插入图片描述

    构造Floyd算法函数
    在这里插入图片描述

    界面实现

    在Widget标出村落
    在这里插入图片描述

    共54个村落标注点,接收起点终点,进行画线
    在这里插入图片描述

    构造放大和缩小地图功能槽函数
    在这里插入图片描述

    源码展示

    .pro文件

    #-------------------------------------------------
    #
    # Project created by QtCreator 2023-09-22T10:19:55
    #
    #-------------------------------------------------
    
    QT       += core gui
    QT += xml
    greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
    
    TARGET = cheshi
    TEMPLATE = app
    
    # The following define makes your compiler emit warnings if you use
    # any feature of Qt which as been marked as deprecated (the exact warnings
    # depend on your compiler). Please consult the documentation of the
    # deprecated API in order to know how to port your code away from it.
    DEFINES += QT_DEPRECATED_WARNINGS
    
    # You can also make your code fail to compile if you use deprecated APIs.
    # In order to do so, uncomment the following line.
    # You can also select to disable deprecated APIs only up to a certain version of Qt.
    #DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000    # disables all the APIs deprecated before Qt 6.0.0
    
    
    SOURCES += \
            main.cpp \
            mainwindow.cpp
    
    HEADERS += \
            mainwindow.h
    
    FORMS += \
            mainwindow.ui
    
    RESOURCES += \
        resourcefile.qrc
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38

    mainwindow.h文件

    #ifndef MAINWINDOW_H
    #define MAINWINDOW_H
    
    #include 
    #include 
    #include 
    #include 
    #include 
    #include 
    #include 
    #include 
    #include 
    #include 
    #include 
    #include 
    #include 
    
    const int INF = 10000000;
    int ressssssssss(int x);
    
    namespace Ui {
    class MainWindow;
    }
    
    class MainWindow : public QMainWindow
    {
        Q_OBJECT
    
    public:
        explicit MainWindow(QWidget *parent = 0);
        ~MainWindow();
        //void on_InButton_clicked();
        //void on_OutButton_clicked();
        void showComBox();
        void zoomInOut();
        void floyd(int n);
        void initDist();
        void getPath(int start, int end);
        void initMap();
        void click();
    private slots:
        void InButton_clicked();
        void OutButton_clicked();
        void showShortPath();
        void shortBtnclicked();
    
    protected:
        void paintEvent(QPaintEvent *event) override;
    private:
        Ui::MainWindow *ui;
    
    };
    struct coordinates  //对应的经纬度坐标(double)
    {
        int id;
        double lon;
        double lat;
    };
    struct coordinatesStr  //对应的经纬度坐标(QString)
    {
        QString id;
        QString lon;
        QString lat;
    };
    struct coordinatesInt //对应的经纬度坐标(int)
    {
        QString id;
        int x;
        int y;
    };
    
    class resolve_xml
    {
    public:
        double degreesToRadians(double degrees);
        double radiansToDegrees(double radians);
        double calculateDistance(coordinates node1, coordinates node2);
        void saveNode(int id,coordinates node);
        void strChangeDouble(coordinatesStr node);
        void findCommonNode();
        void changeCoor(QString strId);
        int imortant();
        std::map<QString,coordinatesInt>doubleCoorMap;
        std::vector<coordinatesInt>doubleCoor;
        std::vector<coordinatesInt>doubleWay;
        double minLat;     //最小纬度
        double maxLat;     //最大经度
        double minLon;
        double maxLon;
    };
    class Graph {
    public:
        int vertices = 54;
        std::vector<int>result;
        std::vector<std::vector<int>> distance;
        std::vector<std::vector<int>> next;
        void addEdge(int source, int destination, int weight) {
            distance[source][destination] = weight;
            next[source][destination] = destination;
        }
    
        void floydWarshall() {
        //distance.assign(54, std::vector(54, INF));
        next.assign(54, std::vector<int>(54, -1));
            for (int k = 0; k < vertices; ++k) {
                for (int i = 0; i < vertices; ++i) {
                    for (int j = 0; j < vertices; ++j) {
                        if (distance[i][k] != INF && distance[k][j] != INF && distance[i][k] + distance[k][j] < distance[i][j]) {
                            distance[i][j] = distance[i][k] + distance[k][j];
                            next[i][j] = next[i][k];
                        }
                    }
                }
            }
        }
    
        void printShortestPath(int start, int end) {
            if (distance[start][end] == INF) {
                //cout << "No path exists from Node " << start << " to Node " << end << endl;
                return;
            }
    
            //cout << "Shortest Path from Node " << start << " to Node " << end << ": ";
            result.push_back(start);
    
            while (start != end) {
                start = next[start][end];
                //cout << " -> " << start;
                result.push_back(start);
            }
    
        }
    };
    
    
    #endif // MAINWINDOW_H
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111
    • 112
    • 113
    • 114
    • 115
    • 116
    • 117
    • 118
    • 119
    • 120
    • 121
    • 122
    • 123
    • 124
    • 125
    • 126
    • 127
    • 128
    • 129
    • 130
    • 131
    • 132
    • 133
    • 134
    • 135
    • 136

    mainwindow.cpp文件

    #include "mainwindow.h"
    #include "ui_mainwindow.h"
    #include 
    #include 
    #include 
    #include 
    
    const int MAXN = 10000000;
    
    Graph grap;
    int n = 54;
    //std::vector> prev(n, std::vector(n, -1));
    std::map<QString,coordinatesStr>mp;
    std::map<QString,coordinates>doubleMap;
    std::vector<QString>commonNode;
    std::map<QString,QString>mapVillage;
    std::map<QString,std::vector<QString>>mapWay;
    std::map<QString,int>villageToInt;
    std::map<int,QString>villageToString;
    std::vector<QString>nodeVillage;
    
    //ui->graphicsView->setScene(scene);
    
    int dist[54][54];  // 保存点与点之间的距离
    int prev[100][100];  // 保存路径上的前一个点
    std::vector<int> path;  // 存储最短路径上的点
    int Matrix[54][54] = {0};
    resolve_xml Xml;
    
    double resolve_xml::degreesToRadians(double degrees) {
        return degrees * M_PI / 180;
    }
    double resolve_xml::radiansToDegrees(double radians) {
        return radians * 180 / M_PI;
    }
    double resolve_xml::calculateDistance(coordinates node1, coordinates node2) { //经纬度坐标
        double dLat = degreesToRadians(node2.lat - node1.lat);   //Haversine公式
        double dLon = degreesToRadians(node2.lon - node1.lon);
        double a = std::sin(dLat / 2) * std::sin(dLat / 2) +
                   std::cos(degreesToRadians(node1.lat)) * std::cos(degreesToRadians(node2.lat)) *
                   std::sin(dLon / 2) * std::sin(dLon / 2);
        double c = 2 * std::atan2(std::sqrt(a), std::sqrt(1 - a));
        double distance = 6378137 * c;
        return distance;
    }
    
    void resolve_xml::strChangeDouble(coordinatesStr node)
    {
        coordinates coor;
        coor.id = node.id.toInt();
        coor.lat = node.lat.toDouble();
        coor.lon = node.lon.toDouble();
        doubleMap[node.id] = coor;
    }
    
    void resolve_xml::findCommonNode() //查找公共交点
    {
        QFile file(":/qrc/map.osm");
        if (!file.open(QIODevice::ReadOnly | QIODevice::Text))
        {
                qDebug() << "无法打开XML文件.";
                //exit(0);
        }
        QXmlStreamReader xml(&file);
    
        std::set<QString> wayNodes;
    
        int wayCount = 0;
        bool flag = false;
    
        while (!xml.atEnd() && !xml.hasError()) {
            QXmlStreamReader::TokenType token = xml.readNext();
            if (token == QXmlStreamReader::StartElement) {
                if (xml.name() == "way") {
                    flag = true;
                }
                else if (xml.name() == "nd" && flag == true) {
                    QString ndRef = xml.attributes().value("ref").toString();
                    if (wayNodes.find(ndRef) != wayNodes.end()) {
                        commonNode.push_back(ndRef);
                    }
                    else {
                        wayNodes.insert(ndRef);
                    }
                }
                else if(xml.name() == "relation"){
                    flag = false;
                }
                else if(xml.name() == "member"){
                    flag = false;
                }
            }
        }
        file.close();
    }
    
    void resolve_xml::changeCoor(QString strId)
    {
        coordinates coo = doubleMap[strId];
        coordinatesInt cooint ;
        int width = (maxLon - minLon) * 10000;
        int length = (maxLat - minLat) * 10000;
        int x = (maxLat - coo.lat ) * 10000 ;
        int y = (coo.lon - minLon) * 10000 ;
        cooint.id = strId;
        cooint.x = y;
        cooint.y = x;
        Xml.doubleCoor.push_back(cooint);
        Xml.doubleCoorMap[strId] = cooint;
    }
    /*void resolve_xml::saveNode(int id,coordinates node)
    {
        mp[id] = node;
    }*/
    int resolve_xml::  imortant()
    {
    
        std::vector<QString>strNode;
        std::vector<QString>strWay;
        coordinatesStr coorStr;   //QString类型经纬度的结构体
        QString wayId;      //way的Id
        QString tagKey;
        QString tagValue;
        QString nodeId;     //node的ID
        QString nodeLon;    //node的经度
        QString nodeLat;    //node的纬度
        QFile fileName(":/qrc/map.osm");
        if (!fileName.open(QIODevice::ReadOnly | QIODevice::Text))
        {
                qDebug() << "无法打开XML文件.";
                return 1;
        }
        QXmlStreamReader xml(&fileName);
            while (!xml.atEnd() && !xml.hasError()) {
                QXmlStreamReader::TokenType token = xml.readNext();
    
                if (token == QXmlStreamReader::StartElement) {
                    if(xml.name() == "node"){
                        nodeId = xml.attributes().value("id").toString();
                        nodeLon = xml.attributes().value("lon").toString();
                        nodeLat = xml.attributes().value("lat").toString();
                        coorStr.id = nodeId;
                        coorStr.lat = nodeLat;
                        coorStr.lon = nodeLon;
                        mp[nodeId] = coorStr;
                        strNode.push_back(nodeId);
                    }
                    else if (xml.name() == "way") {
                        // 提取way元素的id属性值
                        strWay.clear();
                        wayId = xml.attributes().value("id").toString();
                        //qDebug() << "Way ID:" << wayId;
                    } else if (xml.name() == "nd") {
                        // 提取nd元素的ref属性值
                        QString ndRef = xml.attributes().value("ref").toString();
                        strWay.push_back(ndRef);
                        mapWay[wayId] = strWay;
                        //qDebug() << "ND Ref:" << ndRef;
                    } else if (xml.name() == "tag") {
                        // 提取tag元素的k和v属性值
                        QString str1 = tagKey;
                        QString str2 = tagValue;
                        tagKey = xml.attributes().value("k").toString();
                        tagValue = xml.attributes().value("v").toString();
                        if(tagValue == "village")
                        {
                            nodeVillage.push_back(str2);
                            mapVillage[str2] = nodeId;
                        }
                        //qDebug() << "Tag Key:" << tagKey << ", Value:" << tagValue;
                    }
                    else if(xml.name() == "bounds")
                    {
                        //提取数据中的最大最小经纬度
                        Xml.minLat = xml.attributes().value("minlat").toString().toDouble();
                        Xml.minLon = xml.attributes().value("minlon").toString().toDouble();
                        Xml.maxLat = xml.attributes().value("maxlat").toString().toDouble();
                        Xml.maxLon = xml.attributes().value("maxlon").toString().toDouble();
                    }
                }
            }
           if (xml.hasError())
           {
               qDebug() << "XML解析错误: " << xml.errorString();
               return 1;
           }
          for(auto it = mp.begin();it != mp.end();it++) //将QString的经纬度转化成double类型的经纬度
          {
              QString Id = it->first;
              coordinatesStr jw = it->second;
              Xml.strChangeDouble(jw);
              Xml.changeCoor(Id);
              //qDebug()<
              //qDebug()<
          }
          for(auto it = mapWay.begin();it != mapWay.end();it++)
          {
              std::vector<QString> Strway = it->second;
              for(int i = 0;i < Strway.size();i++)
              {
                    QString Qstr = Strway[i];
                    double x = doubleMap[Qstr].lat;
                    double y = doubleMap[Qstr].lon;
                    minLat = std::min(minLat,x);
                    minLon = std::min(minLon,y);
                    maxLat = std::max(maxLat,x);
                    maxLon = std::max(maxLon,y);
              }
          }
         // qDebug()<<"xxxx"<
          for(auto it = mapWay.begin();it != mapWay.end();it++) //保存所有way的点
          {
              QString way = it->first;
              std::vector<QString> Strway = it->second;
              for(int i = 0;i < Strway.size();i++)
              {
                    QString Qstr = Strway[i];
                    //Xml.changeCoor(Qstr);
              }
          }
          for(auto it = mapWay.begin();it != mapWay.end();it++) //根据经纬度计算点与点之间距离,连接成路
          {
              QString way = it->first;
              //qDebug()<
              std::vector<QString> Strway = it->second;
              //qDebug()<<"way nodeNumber:"<
              int distanceWay = 0;
              for(int i = 1;i < Strway.size();i++)
              {
                    QString Qstr1 = Strway[i-1];
                    QString Qstr2 = Strway[i];
                    coordinates node1 = doubleMap[Qstr1];
                    coordinates node2 = doubleMap[Qstr2];
                    distanceWay += (int)Xml.calculateDistance(node1,node2);
              }
              //qDebug()<<"way distance:"<
          }
          for(auto it = mapVillage.begin();it != mapVillage.end();it++)
          {
              //qDebug()<<"village: "<first<<"village nodeId: "<second;
          }
          for(int i = 0;i < nodeVillage.size();i++)
          {
              QString sst = nodeVillage[i];
              villageToInt[sst] = i;
              villageToString[i] = sst;
              //qDebug()<
          }
          /*QString str = "121.1458065";
          bool ok;
          double value = str.toDouble(&ok);
          if (ok) {
              qDebug() << "Converted value:" << value;
          } else {
              qDebug() << "Conversion failed.";
          }*/
          Xml.findCommonNode();
          for(int i = 0;i < commonNode.size();i++)
          {
              //qDebug()<<"commonNode"<
          }
          //qDebug()<<"commonNode size"<
          //qDebug()<<"---"<
          fileName.close();
          return 0;
    }
    
    
    MainWindow::MainWindow(QWidget *parent) :
        QMainWindow(parent),
        ui(new Ui::MainWindow)
    {
        ui->setupUi(this);
    }
    MainWindow::~MainWindow()
    {
        delete ui;
    }
    
    void MainWindow::showComBox()
    {
        for(auto it = mapVillage.begin();it != mapVillage.end();it++)
        {
            QString stt = it->first;
            ui->startBox->addItem(stt);
        }
        for(auto it = mapVillage.begin();it != mapVillage.end();it++)
        {
            QString stt = it->first;
            ui->endBox->addItem(stt);
        }
        qDebug()<<mapVillage.size();
    }
    
    void MainWindow::zoomInOut()
    {
        // 连接放大按钮
        connect(ui->InButton, &QPushButton::clicked, this, &MainWindow::InButton_clicked);
    
        // 连接缩小按钮
        connect(ui->outButton, &QPushButton::clicked, this, &MainWindow::OutButton_clicked);
    
        //连接最短路径按钮
        connect(ui->shortBtn, &QPushButton::clicked, this, &MainWindow::shortBtnclicked);
    }
    
    void MainWindow::InButton_clicked()
    {
        qDebug() << "InButton was clicked or triggered!";
        double scaleFactor = 1.15;
        ui->graphicsView->scale(scaleFactor, scaleFactor);
    }
    
    void MainWindow::OutButton_clicked()
    {
        double scaleFactor = 1.15;
        ui->graphicsView->scale(1.0 / scaleFactor, 1.0 / scaleFactor);
    }
    
    void MainWindow::showShortPath()
    {
    
        QGraphicsScene *scene = ui->graphicsView->scene();
        ui->graphicsView->setRenderHint(QPainter::Antialiasing);  //抗锯齿功能,画的线更润换
       // ui->graphicsView->setScene(scene);
        std::vector<QPointF>shortPath;
        QPainterPath pathVillage;
        for(int i = 0;i < path.size();i++)
        {
            int  intId = path[i];
            QString StrID = villageToString[intId];
            coordinatesInt coorvillage = Xml.doubleCoorMap[mapVillage[StrID]];
            QPointF points;
            points.setX(coorvillage.x);
            points.setY(coorvillage.y);
            shortPath.push_back(points);
        }
        qDebug()<<shortPath.size();
        int distance;
        for(int i = 1;i < path.size();i++)
        {
            int  intId1 = path[i-1];
            int  intId2 = path[i];
            QString StrID1 = villageToString[intId1];
            QString StrID2 = villageToString[intId2];
            coordinates node1 = doubleMap[mapVillage[StrID1]];
            coordinates node2 = doubleMap[mapVillage[StrID2]];
            distance = Xml.calculateDistance(node1,node2);
        }
        QString setdist = QString::number(distance);
        setdist += " meter";
        ui->showDist->setText(setdist);
        /*if(shortPath.size() != 0)
        {
    
            pathVillage.moveTo(shortPath[0]);
            for(int i = 1;i addItem(pathItems);
    
            // 可选:设置道路的样式
            QPen roadPenVillage(Qt::green, 2);  // 示例:绿色,线宽为3
            pathItems->setPen(roadPenVillage);
        }*/
        if(!scene) {
            scene = new QGraphicsScene(this);
            ui->graphicsView->setScene(scene);
        }
        for( int i = 1; i < shortPath.size();i++)
        {
            QPen pen(Qt::red);
            pen.setWidth(3);
            QPointF point1 = shortPath[i-1];
            QPointF point2 = shortPath[i];
            scene->addLine(point1.x(), point1.y(), point2.x(), point2.y(), pen);  // 这里使用红色画笔
        }
    }
    
    void MainWindow::floyd(int n)
    {
        for(int k = 0; k < n; k++) {
            for(int i = 0; i < n; i++) {
                for(int j = 0; j < n; j++) {
                    if(dist[i][k] != INT_MAX && dist[k][j] != INT_MAX && dist[i][j] > dist[i][k] + dist[k][j]) {
                        dist[i][j] = dist[i][k] + dist[k][j];
                        prev[i][j] = k;
                    }
                }
            }
        }
    }
    
    void MainWindow::initDist()
    {
        n = 54;
        for(int i = 0; i < n; i++) {
            for(int j = 0; j < n; j++) {
                if(i == j) dist[i][j] = 0;
                else  if ( j % 2 == 0)
                {
                    QString s1 = villageToString[i];
                    QString s2 = villageToString[j];
                    coordinates node1 = doubleMap[mapVillage[s1]];
                    coordinates node2 = doubleMap[mapVillage[s2]];
                    int distancesss = Xml.calculateDistance(node1,node2);
                    qDebug()<<"s="<<distancesss;
                    dist[i][j] = distancesss;
                }
                /*else if (Matrix[i][j] == 0)
                {
                    dist[i][j] = INT_MAX;
                }*/
                prev[i][j] = i;
            }
        }
    }
    
    void MainWindow::getPath(int start, int end)
    {
        //if(start != end) getPath(start, prev[start][end]);
        //path.push_back(end);
        //path.clear();
        /*QString cur1 = ui->startBox->currentText();
        QString cur2 = ui->endBox->currentText();
        int current1 = villageToInt[cur1];
        int current2 = villageToInt[cur2];
        path.push_back(current1);
        while (current1 != current2) {
            current1 = prev[current1][current2];
            path.push_back(current1);
        }*//*
        if (prev[start][end] == -1) {
                return ;
            }
    
            path.push_back(start);
            while (start != end) {
                start = prev[start][end];
                path.push_back(start);
            }*/
        /*if (start == end || prev[start][end] == -1) {
                // 如果已经到达终点或者无法到达,返回包含起点的路径
                return {start};
            } else {
                // 递归调用,将路径从起点到 next[start][end] 和从 next[start][end] 到终点连接起来
                std::vector path1 = getPath(start, prev[start][end]);
                std::vector path2 = getPath(prev[start][end], end);
    
                // 合并两个路径
                path1.insert(path1.end(), path2.begin() + 1, path2.end());
                return path1;
            }*/
        if(start != end) getPath(start, prev[start][end]);
            path.push_back(end);
    }
    
    void MainWindow::initMap()
    {
        Matrix[0][32] = Matrix[32][0] = 1;
        Matrix[0][53] = Matrix[53][0] = 1;
        Matrix[0][48] = Matrix[48][0] = 1;
        Matrix[0][47] = Matrix[47][0] = 1;
        Matrix[0][49] = Matrix[49][0] = 1;
        Matrix[0][50] = Matrix[50][0] = 1;
        Matrix[0][51] = Matrix[51][0] = 1;
        Matrix[0][36] = Matrix[36][0] = 1;
        Matrix[0][35] = Matrix[35][0] = 1;
        Matrix[0][34] = Matrix[34][0] = 1;
        Matrix[0][37] = Matrix[37][0] = 1;
        Matrix[0][40] = Matrix[40][0] = 1;
        Matrix[0][50] = Matrix[50][0] = 1;
        Matrix[2][33] = Matrix[33][2] = 1;
        Matrix[2][3] = Matrix[3][2] = 1;
        Matrix[2][4] = Matrix[4][2] = 1;
        Matrix[4][3] = Matrix[3][4] = 1;
        Matrix[4][33] = Matrix[33][4] = 1;
        Matrix[5][8] = Matrix[8][5] = 1;
        Matrix[5][9] = Matrix[9][5] = 1;
        Matrix[5][10] = Matrix[10][5] = 1;
        Matrix[7][6] = Matrix[6][7] = 1;
        Matrix[7][4] = Matrix[4][7] = 1;
        Matrix[11][43] = Matrix[43][11] = 1;
        Matrix[11][45] = Matrix[45][11] = 1;
        Matrix[11][42] = Matrix[42][11] = 1;
        Matrix[12][13] = Matrix[13][12] = 1;
        Matrix[12][14] = Matrix[14][12] = 1;
        Matrix[12][15] = Matrix[15][12] = 1;
        Matrix[16][20] = Matrix[20][16] = 1;
        Matrix[17][19] = Matrix[19][17] = 1;
        Matrix[17][18] = Matrix[18][17] = 1;
        Matrix[20][17] = Matrix[17][20] = 1;
        Matrix[20][18] = Matrix[18][20] = 1;
        Matrix[20][19] = Matrix[19][20] = 1;
        Matrix[21][22] = Matrix[22][21] = 1;
        Matrix[21][23] = Matrix[23][21] = 1;
        Matrix[21][26] = Matrix[26][21] = 1;
        Matrix[26][27] = Matrix[27][26] = 1;
        Matrix[26][24] = Matrix[24][26] = 1;
        Matrix[24][25] = Matrix[25][24] = 1;
        Matrix[25][31] = Matrix[31][25] = 1;
        Matrix[28][29] = Matrix[29][28] = 1;
        Matrix[28][30] = Matrix[30][28] = 1;
        Matrix[34][36] = Matrix[36][34] = 1;
        Matrix[35][36] = Matrix[36][35] = 1;
        Matrix[40][34] = Matrix[34][40] = 1;
        Matrix[40][37] = Matrix[37][40] = 1;
        Matrix[41][37] = Matrix[37][41] = 1;
        Matrix[41][34] = Matrix[34][41] = 1;
    
        Matrix[44][39] = Matrix[39][44] = 1;
    
        Matrix[39][38] = Matrix[38][39] = 1;
    }
    
    void MainWindow::click()
    {
        test newobj(this);
        newobj.useMainWindowUI();
    
    }
    void MainWindow::paintEvent(QPaintEvent *event)
    {
        QMainWindow::paintEvent(event);  // 调用父类的 paintEvent 以确保其他部分绘制正确
        /*QPainter painter(this);
        QPen pen;
        pen.setWidth(2);
        painter.setPen(pen);
        qDebug()<<"   "<
    
        QGraphicsScene *scene = new QGraphicsScene(this);
        ui->graphicsView->setScene(scene);
        ui->graphicsView->setRenderHint(QPainter::Antialiasing); //抗锯齿
    
        // 示例点位和名字
        /*int len = nodeVillage.size();
        QList points;
        for(int i = 0;i < len;i++)
        {
            QString villageNode = mapVillage[nodeVillage[i]];
            QPoint ppp;
            coordinatesInt coo = Xml.doubleCoorMap[villageNode];
            ppp.setX(coo.x);
            ppp.setY(coo.y);
            points.push_back(ppp);
            //qDebug()<addEllipse(points[i].x() - 5, points[i].y() - 5, 10, 10, QPen(Qt::black), QBrush(Qt::red));
    
            // 创建一个文本项以显示名字
            QGraphicsTextItem *text = scene->addText(nodeVillage[i]);
            text->setPos(points[i].x() + 10, points[i].y() - text->boundingRect().height() / 2);
        }*/
    
        std::vector<std::vector<QPointF>>roads;
        for(auto it = mapWay.begin();it != mapWay.end();it++)
        {
            std::vector<QString> vectorStr = it->second;
            std::vector<QPointF>roadWay;
            for(int i = 0;i < vectorStr.size();i++)
            {
                QString wayStr = vectorStr[i];
                coordinatesInt coorWay;
                coorWay = Xml.doubleCoorMap[wayStr];
                QPoint pointWay;
                pointWay.setX(coorWay.x);
                pointWay.setY(coorWay.y);
                roadWay.push_back(pointWay);
            }
            roads.push_back(roadWay);
            roadWay.clear();
        }
    
        for (const std::vector<QPointF> &road : roads) {
            QPainterPath pathsss;
            pathsss.moveTo(road[0]);
            for (int i = 1; i < road.size(); ++i)
            {
                pathsss.lineTo(road[i]);
            }
            QGraphicsPathItem *pathItem = new QGraphicsPathItem(pathsss);
            scene->addItem(pathItem);
    
            // 可选:设置道路的样式
            QPen roadPen(Qt::blue, 2);  // 示例:蓝色,线宽为2
            pathItem->setPen(roadPen);
        }
    
        // 示例点位和名字
        int len = nodeVillage.size();
        QList<QPointF> points;
        for(int i = 0;i < len;i++)
        {
            QString villageNode = mapVillage[nodeVillage[i]];
            QPoint ppp;
            coordinatesInt coo = Xml.doubleCoorMap[villageNode];
            ppp.setX(coo.x);
            ppp.setY(coo.y);
            points.push_back(ppp);
            //qDebug()<
        }
    
        for(int i = 0; i < nodeVillage.size(); ++i)
        {
            // 为每个点位创建一个小的椭圆
            QGraphicsEllipseItem *ellipse = scene->addEllipse(points[i].x() - 5, points[i].y() - 5, 10, 10, QPen(Qt::black), QBrush(Qt::red));
    
            // 创建一个文本项以显示名字
            QGraphicsTextItem *text = scene->addText(nodeVillage[i]);
            text->setPos(points[i].x() + 10, points[i].y() - text->boundingRect().height() / 2);
        }
    }
    class CustomGraphicsView : public QGraphicsView //放大缩小只能点击,不能使用滚轮
    {
        Q_OBJECT
    public:
        explicit CustomGraphicsView(QWidget* parent = nullptr)
            : QGraphicsView(parent) {}
    
    protected:
        void wheelEvent(QWheelEvent* event) override
        {
    
        }
    };
    
    
    void MainWindow::shortBtnclicked()
    {
        //initMap();
        /*for(int i = 0;i < 54;i++)
        {
            for(int j = 0;j < 54;j++)
            {
                if(i == j)
                {
                    grap.addEdge(i,j,0);
                }
                else
                {
                    if(Matrix[i][j] == 1)
                    {
                        QString s1 = villageToString[i];
                        QString s2 = villageToString[j];
                        coordinates node1 = doubleMap[mapVillage[s1]];
                        coordinates node2 = doubleMap[mapVillage[s2]];
                        int distancesss = Xml.calculateDistance(node1,node2);
                        qDebug()<<"s="<
        initDist();
        floyd(54);
        QString textBox1 = ui->startBox->currentText();
        QString textBox2 = ui->endBox->currentText();
        int idx1 = villageToInt[textBox1];
        int idx2 = villageToInt[textBox2];
        //grap.printShortestPath(idx1,idx2);
        getPath(idx1,idx2);
        showShortPath();
        //path.clear();
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111
    • 112
    • 113
    • 114
    • 115
    • 116
    • 117
    • 118
    • 119
    • 120
    • 121
    • 122
    • 123
    • 124
    • 125
    • 126
    • 127
    • 128
    • 129
    • 130
    • 131
    • 132
    • 133
    • 134
    • 135
    • 136
    • 137
    • 138
    • 139
    • 140
    • 141
    • 142
    • 143
    • 144
    • 145
    • 146
    • 147
    • 148
    • 149
    • 150
    • 151
    • 152
    • 153
    • 154
    • 155
    • 156
    • 157
    • 158
    • 159
    • 160
    • 161
    • 162
    • 163
    • 164
    • 165
    • 166
    • 167
    • 168
    • 169
    • 170
    • 171
    • 172
    • 173
    • 174
    • 175
    • 176
    • 177
    • 178
    • 179
    • 180
    • 181
    • 182
    • 183
    • 184
    • 185
    • 186
    • 187
    • 188
    • 189
    • 190
    • 191
    • 192
    • 193
    • 194
    • 195
    • 196
    • 197
    • 198
    • 199
    • 200
    • 201
    • 202
    • 203
    • 204
    • 205
    • 206
    • 207
    • 208
    • 209
    • 210
    • 211
    • 212
    • 213
    • 214
    • 215
    • 216
    • 217
    • 218
    • 219
    • 220
    • 221
    • 222
    • 223
    • 224
    • 225
    • 226
    • 227
    • 228
    • 229
    • 230
    • 231
    • 232
    • 233
    • 234
    • 235
    • 236
    • 237
    • 238
    • 239
    • 240
    • 241
    • 242
    • 243
    • 244
    • 245
    • 246
    • 247
    • 248
    • 249
    • 250
    • 251
    • 252
    • 253
    • 254
    • 255
    • 256
    • 257
    • 258
    • 259
    • 260
    • 261
    • 262
    • 263
    • 264
    • 265
    • 266
    • 267
    • 268
    • 269
    • 270
    • 271
    • 272
    • 273
    • 274
    • 275
    • 276
    • 277
    • 278
    • 279
    • 280
    • 281
    • 282
    • 283
    • 284
    • 285
    • 286
    • 287
    • 288
    • 289
    • 290
    • 291
    • 292
    • 293
    • 294
    • 295
    • 296
    • 297
    • 298
    • 299
    • 300
    • 301
    • 302
    • 303
    • 304
    • 305
    • 306
    • 307
    • 308
    • 309
    • 310
    • 311
    • 312
    • 313
    • 314
    • 315
    • 316
    • 317
    • 318
    • 319
    • 320
    • 321
    • 322
    • 323
    • 324
    • 325
    • 326
    • 327
    • 328
    • 329
    • 330
    • 331
    • 332
    • 333
    • 334
    • 335
    • 336
    • 337
    • 338
    • 339
    • 340
    • 341
    • 342
    • 343
    • 344
    • 345
    • 346
    • 347
    • 348
    • 349
    • 350
    • 351
    • 352
    • 353
    • 354
    • 355
    • 356
    • 357
    • 358
    • 359
    • 360
    • 361
    • 362
    • 363
    • 364
    • 365
    • 366
    • 367
    • 368
    • 369
    • 370
    • 371
    • 372
    • 373
    • 374
    • 375
    • 376
    • 377
    • 378
    • 379
    • 380
    • 381
    • 382
    • 383
    • 384
    • 385
    • 386
    • 387
    • 388
    • 389
    • 390
    • 391
    • 392
    • 393
    • 394
    • 395
    • 396
    • 397
    • 398
    • 399
    • 400
    • 401
    • 402
    • 403
    • 404
    • 405
    • 406
    • 407
    • 408
    • 409
    • 410
    • 411
    • 412
    • 413
    • 414
    • 415
    • 416
    • 417
    • 418
    • 419
    • 420
    • 421
    • 422
    • 423
    • 424
    • 425
    • 426
    • 427
    • 428
    • 429
    • 430
    • 431
    • 432
    • 433
    • 434
    • 435
    • 436
    • 437
    • 438
    • 439
    • 440
    • 441
    • 442
    • 443
    • 444
    • 445
    • 446
    • 447
    • 448
    • 449
    • 450
    • 451
    • 452
    • 453
    • 454
    • 455
    • 456
    • 457
    • 458
    • 459
    • 460
    • 461
    • 462
    • 463
    • 464
    • 465
    • 466
    • 467
    • 468
    • 469
    • 470
    • 471
    • 472
    • 473
    • 474
    • 475
    • 476
    • 477
    • 478
    • 479
    • 480
    • 481
    • 482
    • 483
    • 484
    • 485
    • 486
    • 487
    • 488
    • 489
    • 490
    • 491
    • 492
    • 493
    • 494
    • 495
    • 496
    • 497
    • 498
    • 499
    • 500
    • 501
    • 502
    • 503
    • 504
    • 505
    • 506
    • 507
    • 508
    • 509
    • 510
    • 511
    • 512
    • 513
    • 514
    • 515
    • 516
    • 517
    • 518
    • 519
    • 520
    • 521
    • 522
    • 523
    • 524
    • 525
    • 526
    • 527
    • 528
    • 529
    • 530
    • 531
    • 532
    • 533
    • 534
    • 535
    • 536
    • 537
    • 538
    • 539
    • 540
    • 541
    • 542
    • 543
    • 544
    • 545
    • 546
    • 547
    • 548
    • 549
    • 550
    • 551
    • 552
    • 553
    • 554
    • 555
    • 556
    • 557
    • 558
    • 559
    • 560
    • 561
    • 562
    • 563
    • 564
    • 565
    • 566
    • 567
    • 568
    • 569
    • 570
    • 571
    • 572
    • 573
    • 574
    • 575
    • 576
    • 577
    • 578
    • 579
    • 580
    • 581
    • 582
    • 583
    • 584
    • 585
    • 586
    • 587
    • 588
    • 589
    • 590
    • 591
    • 592
    • 593
    • 594
    • 595
    • 596
    • 597
    • 598
    • 599
    • 600
    • 601
    • 602
    • 603
    • 604
    • 605
    • 606
    • 607
    • 608
    • 609
    • 610
    • 611
    • 612
    • 613
    • 614
    • 615
    • 616
    • 617
    • 618
    • 619
    • 620
    • 621
    • 622
    • 623
    • 624
    • 625
    • 626
    • 627
    • 628
    • 629
    • 630
    • 631
    • 632
    • 633
    • 634
    • 635
    • 636
    • 637
    • 638
    • 639
    • 640
    • 641
    • 642
    • 643
    • 644
    • 645
    • 646
    • 647
    • 648
    • 649
    • 650
    • 651
    • 652
    • 653
    • 654
    • 655
    • 656
    • 657
    • 658
    • 659
    • 660
    • 661
    • 662
    • 663
    • 664
    • 665
    • 666
    • 667
    • 668
    • 669
    • 670
    • 671
    • 672
    • 673
    • 674
    • 675
    • 676
    • 677
    • 678
    • 679
    • 680
    • 681
    • 682
    • 683
    • 684
    • 685

    成果展示

    在这里插入图片描述

    源码下载 (免费)

    链接: https://pan.baidu.com/s/1Ai4m-X6GwLmkpbQpESRRDw
    提取码: 0703


    更多资料尽在 GitHub 欢迎各位读者去Star

    ⭐学术交流群Q 754410389 持续更新中~~~

  • 相关阅读:
    为什么每个有影响力的内容创作者都需要一个Kadence WordPress网站
    【Apollo】Apollo的入门介绍
    RocketMQ—(总结)一篇就搞懂 RocketMQ
    取证之查看本机保存的WiFi密码
    【多目标优化算法】多目标粘液霉菌算法(MOSMA)附Matlab代码
    【freertos】009-任务控制
    python os.system( 没有那个文件或目录
    【VS插件】VS code上的Remote - SSH
    【Python基础篇011】Python全部内置函数详细认识(中篇)
    【深度学习】卷积神经网络,测试两段代码
  • 原文地址:https://blog.csdn.net/m0_63743577/article/details/133484570