QT怎么将经纬度点连成轨迹

用qt画出来的轨迹图只有白色背景
这是文件中的部分经纬度:
纬度:37.5333785,经度:121.7502517
纬度:37.5333786,经度:121.7502531
纬度:37.5333786,经度:121.7502546
纬度:37.5333786,经度:121.7502561
纬度:37.5333787,经度:121.7502576
纬度:37.5333787,经度:121.7502590
纬度:37.5333787,经度:121.7502605
纬度:37.5333787,经度:121.7502620
纬度:37.5333788,经度:121.7502635
纬度:37.5333788,经度:121.7502650
纬度:37.5333788,经度:121.7502665

#include <QApplication>
#include <QFile>
#include <QPointF>
#include <QVector>
#include <QPainter>
#include <QPixmap>
#include <QDebug>

int main(int argc, char *argv[])
{
    QApplication app(argc, argv);

    // 读取经纬度数据
    QFile file("output.txt");
    if (!file.open(QIODevice::ReadOnly | QIODevice::Text))
    {
        qDebug() << "Failed to open file.";
        return -1;
    }

    QVector<QPointF> points; // 存储经纬度点的容器

    while (!file.atEnd())
    {
        QByteArray line = file.readLine().trimmed();
        QList<QByteArray> coordinates = line.split(',');

        if (coordinates.size() == 2)
        {
            bool ok1, ok2;
            double latitude = coordinates.at(0).mid(4).toDouble(&ok1);
            double longitude = coordinates.at(1).mid(4).toDouble(&ok2);

            if (ok1 && ok2)
            {
                QPointF point(longitude, latitude);
                points.append(point);
            }
        }
    }

    file.close();

    // 创建绘图设备和画笔
    QPixmap pixmap(800, 600);
    pixmap.fill(Qt::white);
    QPainter painter(&pixmap);
    painter.setRenderHint(QPainter::Antialiasing, true);
    painter.setPen(Qt::red);

    // 绘制轨迹
    for (int i = 0; i < points.size() - 1; ++i)
    {
        const QPointF &startPoint = points.at(i);
        const QPointF &endPoint = points.at(i + 1);
        painter.drawLine(startPoint, endPoint);
    }

    // 保存轨迹图像
    pixmap.save("trajectory.png");

    return 0;
}


只有白色背景没轨迹?

先要确保这些经纬度转换成的坐标在你的图片范围内。

回答部分参考、引用ChatGpt以便为您提供更准确的答案:

要实现对角矩阵沿对角线的复制,可以使用NumPy库来进行操作。以下是使用Python和NumPy实现该功能的示例代码:

import numpy as np

# 读取CSV文件内容
data = np.genfromtxt('file.csv', delimiter=',')

# 创建对角矩阵
diagonal_matrix = np.diag(data)

# 将上三角复制到下三角
lower_triangular = np.tril(diagonal_matrix)

# 打印结果
print(lower_triangular)

在代码中,我们首先使用np.genfromtxt函数读取CSV文件的内容,并存储在data变量中。然后,使用np.diag函数创建一个对角矩阵,其中对角线上的元素由data数组提供。接下来,使用np.tril函数将对角矩阵的上三角部分复制到下三角,得到最终的结果。

请注意,您需要将代码中的'file.csv'替换为实际的文件路径,确保文件能够正确读取。

通过以上代码,您可以实现对角矩阵沿对角线的复制,并将上三角部分复制到下三角。

这个问题需要使用Qt的QPainter来实现。以下是一个简单的示例代码来绘制经纬度点的轨迹。你可以根据自己的需求进行调整。

在以下示例中,我们首先读取一个包含经纬度信息的文本文件,然后使用QPointF类来存储所有经纬度点的坐标。最后,我们创建一个QPixmap对象作为画布,使用QPainter在上面绘制经纬度点之间的线条。最终,将轨迹保存为PNG图像。记得要将代码中的 “output.txt” 替换为你自己的文件名。

#include <QApplication>
#include <QFile>
#include <QPointF>
#include <QVector>
#include <QPainter>
#include <QPixmap>
#include <QDebug>

int main(int argc, char *argv[])
{
    QApplication app(argc, argv);

    // 读取经纬度数据
    QFile file("output.txt");
    if (!file.open(QIODevice::ReadOnly | QIODevice::Text))
    {
        qDebug() << "Failed to open file.";
        return -1;
    }

    QVector<QPointF> points; // 存储经纬度点的容器

    while (!file.atEnd())
    {
        QByteArray line = file.readLine().trimmed();
        QList<QByteArray> coordinates = line.split(',');

        if (coordinates.size() == 2)
        {
            bool ok1, ok2;
            double latitude = coordinates.at(0).mid(4).toDouble(&ok1);
            double longitude = coordinates.at(1).mid(4).toDouble(&ok2);

            if (ok1 && ok2)
            {
                QPointF point(longitude, latitude);
                points.append(point);
            }
        }
    }

    file.close();

    // 创建绘图设备和画笔
    QPixmap pixmap(800, 600);
    pixmap.fill(Qt::white);
    QPainter painter(&pixmap);
    painter.setRenderHint(QPainter::Antialiasing, true);
    painter.setPen(Qt::red);

    // 绘制轨迹
    for (int i = 0; i < points.size() - 1; ++i)
    {
        const QPointF &startPoint = points.at(i);
        const QPointF &endPoint = points.at(i + 1);
        painter.drawLine(startPoint, endPoint);
    }

    // 保存轨迹图像
    pixmap.save("trajectory.png");

    return 0;
}


答案参考ChatGPT Plus版,整理汇总。希望能帮助你解决问题根据您提供的代码,画出的轨迹图只有白色背景的问题可能是由于以下原因之一:

  1. 没有正确设置绘图设备的尺寸:您在创建 QPixmap 对象时指定了宽度为 800,高度为 600,如果您希望绘制的轨迹图更大,请适当调整这些值。

  2. 绘图坐标系不正确:根据您提供的经纬度数据,经度应该对应 x 坐标,纬度应该对应 y 坐标。请确保经度在 x 轴方向,纬度在 y 轴方向。

  3. 绘制轨迹时的点坐标问题:请检查经纬度数据的读取和解析过程,确保经纬度值正确提取并转换为坐标点。

请您检查这些可能的问题,并进行相应的调整,以确保正确绘制轨迹图。

  • 以下回答由chatgpt基于相关博客总结生成:

    针对该问题,可以使用QT自带的QPainter类来实现绘制经纬度点的轨迹图。具体步骤如下:

    1. 在QT工程中添加一个widget,作为绘制区域,可以在widget的paintEvent函数中实现绘制轨迹。同时,也可以在该widget上添加其他控件,如放大缩小按钮、坐标轴等。
    2. 读取经纬度数据文件,可以使用QFile类来读取,将数据存储在一个QList或QVector容器中。
    3. 根据经纬度数据计算出每个点在widget中的坐标值,可以使用图形学中的投影变换等方法来实现。
    4. 使用QPainter类来绘制轨迹,可调用drawLine或drawLines函数来实现连接多个点的直线,或者使用drawEllipse函数来绘制每个点。
    5. 可以根据需求对绘制效果进行优化,如添加颜色、线型、粗细等属性。

    下面是一个简单的示例代码:

    // 在widget的paintEvent函数中实现绘制轨迹
    void MyWidget::paintEvent(QPaintEvent *event)
    {
        Q_UNUSED(event);
    
        QPainter painter(this);
        painter.setRenderHint(QPainter::Antialiasing); // 抗锯齿
        painter.setPen(QPen(Qt::red, 2)); // 设置画笔颜色和线宽
    
        // 读取经纬度数据文件
        QFile file("data.txt");
        if (file.open(QIODevice::ReadOnly))
        {
            QVector<QPointF> points; // 存储坐标点
            QTextStream in(&file);
            while (!in.atEnd())
            {
                QString line = in.readLine();
                QStringList list = line.split(",");
                qreal x = list.at(0).toDouble();
                qreal y = list.at(1).toDouble();
                QPointF point(x, y);
                points.append(point);
            }
            file.close();
    
            QVector<QPointF> screenPoints; // 存储屏幕坐标点
            // TODO: 根据经纬度计算出屏幕坐标
    
            painter.drawPolyline(screenPoints); // 绘制轨迹
        }
    }
    
    // 根据经纬度计算屏幕坐标
    void MyWidget::calScreenPoints(const QVector<QPointF> &points, QVector<QPointF> &screenPoints)
    {
        // TODO: 实现投影变换等算法,将经纬度坐标转换为屏幕坐标
    }
    

    另外,关于绘制背景颜色的问题,可以在widget的构造函数中设置背景色,或者通过setStyleSheet函数设置背景色,例如:

    // 设置widget背景颜色为白色
    this->setAutoFillBackground(true);
    QPalette palette = this->palette();
    palette.setColor(QPalette::Background, Qt::white);
    this->setPalette(palette);
    
    // 或者通过setStyleSheet设置背景色
    QString styleSheet = "background-color: white;";
    this->setStyleSheet(styleSheet);
    

将背景色先换个颜色

按照范围出图就可以,参考如下代码:
这是运行结果,如果范围不合适可以再调整一下:

img

#include <QApplication>
#include <QFile>
#include <QPointF>
#include <QVector>
#include <QPainter>
#include <QPixmap>
#include <QDebug>

int main(int argc, char *argv[])
{
    QApplication app(argc, argv);


    // 读取经纬度数据
    QFile file("output.txt");
    if (!file.open(QIODevice::ReadOnly | QIODevice::Text))
    {
        qDebug() << "Failed to open file.";
        return -1;
    }

    QVector<QPointF> points; // 存储经纬度点的容器

    while (!file.atEnd())
    {
        QByteArray line = file.readLine().trimmed();
        QList<QByteArray> coordinates = line.split(',');

        if (coordinates.size() == 2)
        {
            bool ok1, ok2;
            double latitude = coordinates.at(0).mid(9).toDouble(&ok1);
            double longitude = coordinates.at(1).mid(9).toDouble(&ok2);

            if (ok1 && ok2)
            {
                QPointF point(longitude, latitude);
                points.append(point);
            }
        }
    }

    file.close();

    // 创建绘图设备和画笔
    QPixmap pixmap(800, 600);
    pixmap.fill(Qt::white);
    QPainter painter(&pixmap);
    painter.setRenderHint(QPainter::Antialiasing, true);
    painter.setPen(Qt::red);

    // 绘制轨迹
    for (int i = 0; i < points.size() - 1; ++i)
    {
        const QPointF &startPoint = points.at(i) - points.at(0);
        const QPointF &endPoint = points.at(i + 1) - points.at(0);
        painter.drawLine(startPoint*1e7, endPoint*1e7);
    }

    // 保存轨迹图像
    pixmap.save("trajectory.png");

    return 0;
}



引用chatgpt:
在绘制轨迹时,需要设置画笔的宽度以使轨迹更加清晰。你可以将painter.setPen(Qt::red)修改为painter.setPen(Qt::red, 2),这样就可以在文件中看到更清晰的轨迹了。完整的代码如下:

#include <QApplication>
#include <QFile>
#include <QPointF>
#include <QVector>
#include <QPainter>
#include <QPixmap>
#include <QDebug>

int main(int argc, char *argv[])
{
    QApplication app(argc, argv);

    // 读取经纬度数据
    QFile file("output.txt");
    if (!file.open(QIODevice::ReadOnly | QIODevice::Text))
    {
        qDebug() << "Failed to open file.";
        return -1;
    }

    QVector<QPointF> points; // 存储经纬度点的容器

    while (!file.atEnd())
    {
        QByteArray line = file.readLine().trimmed();
        QList<QByteArray> coordinates = line.split(',');

        if (coordinates.size() == 2)
        {
            bool ok1, ok2;
            double latitude = coordinates.at(0).mid(4).toDouble(&ok1);
            double longitude = coordinates.at(1).mid(4).toDouble(&ok2);

            if (ok1 && ok2)
            {
                QPointF point(longitude, latitude);
                points.append(point);
            }
        }
    }

    file.close();

    // 创建绘图设备和画笔
    QPixmap pixmap(800, 600);
    pixmap.fill(Qt::white);
    QPainter painter(&pixmap);
    painter.setRenderHint(QPainter::Antialiasing, true);
    painter.setPen(Qt::red, 2); // 设置画笔宽度为2像素

    // 绘制轨迹
    for (int i = 0; i < points.size() - 1; ++i)
    {
        const QPointF &startPoint = points.at(i);
        const QPointF &endPoint = points.at(i + 1);
        painter.drawLine(startPoint, endPoint);
    }

    // 保存轨迹图像
    pixmap.save("trajectory.png");

    return 0;
}

想问题主最终目标是什么呢,一定要用python么,arcgis软件能直接输入点坐标表,显示轨迹,,cad也能直接粘贴坐标表格画折线。


void MapBaiDu::moveMarker(QStringList &list)
{
    //动态移动点
    list << QString("  function moveMarker(name, point) {");
    list << QString("    if (name.length == 0) {");
    list << QString("      return;");
    list << QString("    }");
    list << QString("    var allOverlay = map.getOverlays();");
    list << QString("    var len = allOverlay.length;");
    list << QString("    for (var i = 0; i < len; i++) {");
    list << QString("      var overlay = allOverlay[i];");
    //过滤只需要标注点 Marker 的图层覆盖物
    list << QString("      if (overlay.toString() != '[object Marker]') {");
    list << QString("        continue;");
    list << QString("      }");
    //过滤没有标签的标注点
    list << QString("      var label = overlay.getLabel();");
    list << QString("      if (label == null) {");
    list << QString("        continue;");
    list << QString("      }");
    list << QString("      if (label.content == name) {");
    list << QString("        var list = point.split(',');");
    list << QString("        var pot = new BMap.Point(list[0], list[1]);");
    list << QString("        var marker = allOverlay[i];");
    list << QString("        marker.setPosition(pot);");
    list << QString("        break;");
    list << QString("      }");
    list << QString("    }");
    list << QString("  }");
}

void frmMapRoute::on_btnSearchRoute_clicked()
{
    QString startAddr = ui->txtStartAddr->text().trimmed();
    QString endAddr = ui->txtEndAddr->text().trimmed();
    if (startAddr.isEmpty() || endAddr.isEmpty()) {
        QUIHelper::showMessageBoxError("起点和终点地址不能为空,请重新填写!");
        return;
    }

    baidu->setRotueInfo(ui->cboxRouteType->currentIndex(), ui->cboxPolicyType->currentIndex(), startAddr, endAddr);
    map->loadMap();

    lastPoint = App::MapCenter;
    ui->rbtnStartAddr->setChecked(true);
    ui->tabWidgetRoute->setCurrentIndex(0);
}

void frmMapRoute::on_btnDrawRoute_clicked()
{
#ifdef webkit
    QUIHelper::showMessageBoxError("webkit不支持数组的数据形式返回!");
    return;
#endif
    if (routeDatas.count() == 0) {
        QUIHelper::showMessageBoxError("请先单击查询路线获取路线的坐标点集合!");
        return;
    }

    //将收到的路径点集合分线段绘制
    foreach (QStringList data, routeDatas) {
        QString points = data.join("|");
        QString js = QString("addPolyline('%1')").arg(points);
        map->runJs(js);
    }
}

void frmMapRoute::on_btnCheckData_clicked()
{
    //第一步:计算总数,求平均值=实际总数/预期总数+1,预期总数>=实际总数则不用处理
    int countSrc = ui->listWidgetSrc->count();
    int countTarget = ui->txtPointCount->text().trimmed().toInt();
    if (countTarget >= countSrc) {
        return;
    }

    //第二步:根据平均值挨个取出值
    QStringList points;
    int avg = countSrc / countTarget + 1;
    for (int i = 0; i < countSrc; i += avg) {
        QString point = ui->listWidgetSrc->item(i)->data(Qt::UserRole).toString();
        points << point;
    }

    //必须加上末尾这个作为结束,如果刚好除尽则不用
    QString point = ui->listWidgetSrc->item(countSrc - 1)->data(Qt::UserRole).toString();
    if (points.last() != point) {
        points << point;
    }

    //第三步:将数据重新填入最终数据列表
    ui->listWidgetTarget->clear();
    for (int i = 0; i < points.count(); ++i) {
        QString point = points.at(i);
        addItem(ui->listWidgetTarget, i, point);
    }

    ui->tabWidgetRoute->setCurrentIndex(1);
    qDebug() << TIMEMS << avg << points.count() << points;
}

void frmMapRoute::on_btnMapWeb_clicked()
{
    //如果是https开头则需要在运行的时候带上openssl的库
    map->loadMap("https://map.baidu.com/");
}

void frmMapRoute::moveMarker()
{
    QString name = "轨迹点";
    QListWidget *listWidget = ui->listWidgetSrc;
    if (!ui->listWidgetSrc->isVisible()) {
        listWidget = ui->listWidgetTarget;
    }

    int row = listWidget->currentRow();
    if (row >= 0 && row < listWidget->count()) {
        QString point = listWidget->currentItem()->data(Qt::UserRole).toString();
        listWidget->setCurrentRow(row + 1);
        QString js = QString("moveMarker('%1', '%2')").arg(name).arg(point);
        map->runJs(js);
    } else {
        on_btnTestData_clicked();
    }
}

void frmMapRoute::on_btnTestData_clicked()
{
    QString name = "轨迹点";
    QListWidget *listWidget = ui->listWidgetSrc;
    if (!ui->listWidgetSrc->isVisible()) {
        listWidget = ui->listWidgetTarget;
    }

    if (ui->btnTestData->text() == "模拟轨迹") {
        //自定义图标
        QString iconfile = "./ipc_robot2.png";
        int iconsize = 50;
        QString js = QString("addMarker('%1', '', '', '', 60, '%1', 0, 0, '%2', %3)")
                .arg(name).arg(iconfile).arg(iconsize);
        map->runJs(js);
        listWidget->setCurrentRow(0);
        ui->tabWidgetRoute->setEnabled(false);
        ui->btnTestData->setText("停止模拟");
        timer->start(100);
        moveMarker();
    } else {
        QString js = QString("deleteMarker('%1')").arg(name);
        map->runJs(js);
        timer->stop();
        ui->tabWidgetRoute->setEnabled(true);
        ui->btnTestData->setText("模拟轨迹");
    }
}

你的QT背景变白,可以检查下是否使用了背景图片等资源导致的文件路径不对的。图片最好是保存在当前工程的资源目录下,使用相对路径。其次,动态轨迹的绘制,可以使用Qt的QTimer类来实现。QTimer类可以定时触发一个信号,我们可以在信号处理函数中实现动态轨迹的绘制。

检查一下点的坐标是否在背景范围内,然后把背景换个颜色试试