QT realiza la conversión de longitud y latitud en coordenadas de píxeles de imagen

QT realiza la conversión de longitud y latitud en coordenadas de píxeles de imagen

Declaración de necesidades

Recientemente encontrado este tipo de demanda en desarrollo, dada la longitud y latitud de la tierra, marque la posición de la longitud y latitud en un mapa de imágenes estáticas.

análisis de demanda

La latitud y la longitud de la Tierra es un sistema de coordenadas esféricas. La imagen es un sistema de coordenadas planas y no se puede convertir directamente. Google Maps utiliza el "método de proyección de Mercator" al convertir una superficie esférica en un plano. (Los estudiantes interesados ​​pueden ir a Baidu) .El sistema de coordenadas todavía está distribuido uniformemente, mientras que las dimensiones no están distribuidas uniformemente.Se requieren cálculos especiales para obtener las coordenadas de píxeles en el sistema de coordenadas plano.

Código

Ejemplo de mapa mundial

Tome el mapa del mundo como ejemplo. El mapa del mundo más grande se captura en Google Maps: longitud -180 grados a 180 grados, latitud -85 grados a 85 grados (la latitud más grande de la tierra es -90 a 90, después de la proyección de Mercator, 90 grados tenderán a Al infinito, el plano no se puede representar), el núcleo del algoritmo es convertir la dimensión desigual en una representación uniforme.
widget.h

#ifndef WIDGET_H
#define WIDGET_H
#include <QWidget>
#include <QPainter>
#include <QImage>
namespace Ui {
    
    
class Widget;
}
struct MAP_X_Y{
    
    
    double x;
    double y;
};
class Widget : public QWidget
{
    
    
    Q_OBJECT
public:
    explicit Widget(QWidget *parent = 0);
    ~Widget();
    void displayPos();//地图显示位置
    MAP_X_Y AxesConvert(double lon,double lat);//经纬度转换为像素坐标
public slots:
    void slotpushButton();
private:
    Ui::Widget *ui;
    QImage *m_pImage;//定义QImage绘图设备
    QPainter *m_pPainter;//定义画家
};
#endif // WIDGET_H

widget.cpp

#include "widget.h"
#include "ui_widget.h"
#include <QPixmap>
#include <QDebug>
#include <QPainter>
#include <QImage>
#include <cmath>
Widget::Widget(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::Widget)
{
    
    
    ui->setupUi(this);
    this->setWindowTitle("世界地图");
    m_pImage = new QImage(1024,1024,QImage::Format_ARGB32);
    m_pPainter = new QPainter(m_pImage);

    m_pPainter->drawImage(0,0,QImage("./images/worldMap.jpg"));
    ui->label->setPixmap(QPixmap::fromImage(*m_pImage));//UI控件显示图片
    connect(ui->pushButton,SIGNAL(clicked(bool)),this,SLOT(slotpushButton()));
}
Widget::~Widget()
{
    
    
    delete ui;
}

/**
 * @brief 显示位置
 */
void Widget::displayPos()
{
    
    
    double lon = ui->lineEdit_lon->text().toDouble();
    double lat = ui->lineEdit_lat->text().toDouble();
    MAP_X_Y t_MAP_X_Y = AxesConvert(lon,lat);//经纬度转换为像素坐标

    m_pPainter->drawImage(0,0,QImage("./images/worldMap.jpg"));

    for(int i=t_MAP_X_Y.x;i<t_MAP_X_Y.x+5;i++)
        for(int j=t_MAP_X_Y.y;j<t_MAP_X_Y.y+5;j++)
        {
    
    
            m_pImage->setPixel(i,j,qRgb(255,0,0));//按像素点修改图片颜色,图片中显示为红色方块
        }
    ui->label->setPixmap(QPixmap::fromImage(*m_pImage));
}

/**
 * @brief 经纬度转换为像素坐标
 * @param lon 经度
 * @param lat 维度
 * @return 像素坐标
 */
MAP_X_Y Widget::AxesConvert(double lon, double lat)
{
    
    
    const double pixel_Width = 1024;//截取地图像素宽度
    const double pixel_Height = 1024;//截取地图像素高度
    const double PI = 3.1415926;
    const double MaxLon = 180;//截取地图的最大经度
    const double MaxLat = 85;//截取地图的最大维度
    int pixel_X;
    int pixel_Y;
    /**
     * @brief google地图中能够截取的最大经度是180度,最大维度是85度
     * 转换为平面坐标系后经度是均匀分布的,维度不是均匀分布
     *经过下面公式计算后,得到的“修正维度”是均匀的,传入MaxLat计算出来的值是修正维度的最大值
     */
    double reviseMaxLat = log(tan((90+MaxLat)*PI/360))/(PI/180);//修正后的最大维度

    lat = log(tan((90+lat)*PI/360))/(PI/180);//修正后的维度
    //平面坐标系可分为4个象限,坐标落在不同象限的计算方式不同
    if(lon>=0 && lat>=0)
    {
    
    
        pixel_X = (lon/MaxLon)*(pixel_Width/2)+pixel_Width/2;
        pixel_Y = (pixel_Height/2) - (lat/reviseMaxLat)*(pixel_Height/2);
    }
    else if(lon>=0 && lat<=0)
    {
    
    
        pixel_X = (lon/MaxLon)*(pixel_Width/2)+pixel_Width/2;
        pixel_Y = (pixel_Height/2) + (-lat/reviseMaxLat)*(pixel_Height/2);
    }
    else if(lon<=0 && lat >=0)
    {
    
    
        pixel_X = pixel_Width/2 - (-lon/MaxLon)*(pixel_Width/2);
        pixel_Y = (pixel_Height/2) - (lat/reviseMaxLat)*(pixel_Height/2);
    }
    else if(lon<=0 && lat<=0)
    {
    
    
        pixel_X = pixel_Width/2 - (-lon/MaxLon)*(pixel_Width/2);
        pixel_Y = (pixel_Height/2) + (-lat/reviseMaxLat)*(pixel_Height/2);
    }

    MAP_X_Y t_sMap;
    t_sMap.x = pixel_X;
    t_sMap.y = pixel_Y;
    return t_sMap;
}

void Widget::slotpushButton()
{
    
    
    displayPos();
}

Representaciones que muestran la ubicación de Beijing
Inserte la descripción de la imagen aquí

Mapa personalizado: alrededores de China

El siguiente es un ejemplo de cómo personalizar un mapa alrededor de China, interceptando el rango de longitud de 60 grados a 160 grados, el rango de latitud de 0 grados a 60 grados y la función de conversión de coordenadas:

/**
 * @brief 经纬度转换为像素坐标
 * @param lon
 * @param lat
 * @return
 */
MAP_X_Y China_Map::AxesConvert_Custom(double lon, double lat)
{
    
    
    const double pixel_Width = 1143;//截取地图像素宽度
    const double pixel_Height = 859;//截取地图像素高度
    const double PI = 3.1415926;
    const double LeftLon = 60;//地图最左侧经度
    const double RightLon = 160;//地图最右侧经度
    const double TopLat = 60;//地图顶部维度
    const double BottomLat = 0;//地图底部维度
    int pixel_X;
    int pixel_Y;
    /**
     * @brief google地图中能够截取的最大经度是180度,最大维度是85度
     * 转换为平面坐标系后经度是均匀分布的,维度不是均匀分布
     *经过下面公式计算后,得到的“修正维度”是均匀的,传入MaxLat计算出来的值是修正维度的最大值
     */
    double reviseMaxLat = log(tan((90+(TopLat))*PI/360))/(PI/180);//修正后的最大维度

    lat = log(tan((90+lat)*PI/360))/(PI/180);//修正后的维度
    //截取的地图经度和维度都大于0,只集中在一个象限
    pixel_X = ((lon - LeftLon)/(RightLon - LeftLon))*pixel_Width;
    pixel_Y = pixel_Height - (lat - BottomLat)/(reviseMaxLat - BottomLat)*pixel_Height;

    MAP_X_Y t_sMap;
    t_sMap.x = pixel_X;
    t_sMap.y = pixel_Y;
    return t_sMap;
}

Representaciones que muestran la ubicación de Nanjing
Inserte la descripción de la imagen aquí

Supongo que te gusta

Origin blog.csdn.net/weixin_40355471/article/details/107748833
Recomendado
Clasificación