WGS84和GCJ09坐标系转换(C++)

WGS84和GCJ09坐标系转换(C++)

#pragma once
#ifndef COORDINATEUTIL_H
#define COORDINATEUTIL_H

/**
 * 坐标转换工具库
 * 1.WGS84 -> GCJ02
 * 2.GCJ02 -> WGS84
 */
#include <QObject>
#include "TransformPosition.h"
class CoordinateUtil : public QQuickItem
{
    Q_OBJECT
public:
    CoordinateUtil();
    Q_INVOKABLE TransformPosition* wgs84toGcj02(double lat, double lng);      //WGS84转GCJ02(火星坐标系)
    Q_INVOKABLE TransformPosition* gcj02toWgs84(double lat, double lng);
private:
    double transformLat(double lat, double lng);    //纬度转换
    double transformLng(double lat, double lng);    //经度转换
    bool outOfChina(double lat, double lng);        //判断是否在国内
signals:

};

#endif // COORDINATEUTIL_H

#include "CoordinateUtil.h"
#include <QtMath>
#include <QDebug>


#ifndef A
#define A (6378245.0)
#endif

#ifndef EE
#define EE (0.00669342162296594323)
#endif

CoordinateUtil::CoordinateUtil()
{

}
bool CoordinateUtil::outOfChina(double lat, double lng)
{
    if (lng < 72.004 || lng > 137.8347) {
        return true;
    } else if (lat < 0.8293 || lat > 55.8271) {
        return true;
    }
    return false;
}
double CoordinateUtil::transformLat(double lat, double lng)
{
    double ret =  -100.0 + 2.0 * lng + 3.0 * lat + 0.2 * lat * lat + 0.1 * lng * lat + 0.2 * qSqrt(qFabs(lng));
    ret += (20.0 * qSin(6.0 * lng * M_PI) + 20.0 * qSin(2.0 * lng * M_PI)) * 2.0 / 3.0;
    ret += (20.0 * qSin(lat * M_PI) + 40.0 * qSin(lat / 3.0 * M_PI)) * 2.0 / 3.0;
    ret += (160.0 * qSin(lat / 12.0 * M_PI) + 320 * qSin(lat * M_PI / 30.0)) * 2.0 / 3.0;
    return ret;
}
double CoordinateUtil::transformLng(double lat, double lng)
{
    double ret = 300.0 + lng + 2.0 * lat + 0.1 * lng * lng + 0.1 * lng * lat + 0.1 * qSqrt(qFabs(lng));
    ret += (20.0 * qSin(6.0 * lng * M_PI) + 20.0 * qSin(2.0 * lng * M_PI)) * 2.0 / 3.0;
    ret += (20.0 * qSin(lng * M_PI) + 40.0 * qSin(lng / 3.0 * M_PI)) * 2.0 / 3.0;
    ret += (150.0 * qSin(lng / 12.0 * M_PI) + 300.0 * qSin(lng / 30.0 * M_PI)) * 2.0 / 3.0;
    return ret;
}
/**
 * @brief CoordinateUtil::wgs84toGcj02 WGS84转GCJ02
 * @param lat WGS84坐标系的经度
 * @param lng WGS84坐标系的纬度
 * @return GCJ02(火星坐标系)
 */
TransformPosition* CoordinateUtil::wgs84toGcj02(double lat, double lng)
{
    TransformPosition *gcj02 = new TransformPosition;
    if(outOfChina(lat, lng)){
        gcj02->init(lat, lng);
    } else {
        double dLat = transformLat(lat-35.0, lng-105.0);
        double dLng = transformLng(lat-35.0, lng-105.0);
        double radLat = lat / 180.0 * M_PI;
        double magic = qSin(radLat);
        magic = 1 - EE * magic * magic;
        double sqrtMagic = qSqrt(magic);

        dLat = (dLat * 180.0) / ((A * (1 - EE)) / (magic * sqrtMagic) * M_PI);
        dLng = (dLng * 180.0) / (A / sqrtMagic * qCos(radLat) * M_PI);
        double mgLat = lat + dLat;
        double mgLng = lng + dLng;
        gcj02->init(mgLat, mgLng);
    }
    return gcj02;
}
/**
 * @brief CoordinateUtil::gcj02toWgs84 GCJ02(火星坐标系)转GPS84
 * @param lat 火星坐标系纬度
 * @param lng 火星坐标系的经度
 * @return WGS84坐标
 */
TransformPosition* CoordinateUtil::gcj02toWgs84(double lat, double lng)
{
    TransformPosition *gcj02 = new TransformPosition;
    if(outOfChina(lat, lng)){
        gcj02->init(lat, lng);
    } else {
        double dLat = transformLat(lat-35.0, lng-105.0);
        double dLng = transformLng(lat-35.0, lng-105.0);
        double radLat = lat / 180.0 * M_PI;
        double magic = qSin(radLat);
        magic = 1 - EE * magic * magic;
        double sqrtMagic = qSqrt(magic);
        dLat = (dLat * 180.0) / ((A * (1 - EE)) / (magic * sqrtMagic) * M_PI);
        dLng = (dLng * 180.0) / (A / sqrtMagic * qCos(radLat) * M_PI);
        double mgLat = lat + dLat;
        double mgLng = lng + dLng;
        gcj02->init(lat * 2 - mgLat, lng *2 - mgLng);

    }
    return gcj02;
}

#ifndef TRANSFORMPOSITION_H
#define TRANSFORMPOSITION_H

#include <QQuickItem>
/**
 * @brief The TransformPosition class
 * 转后后的坐标实体
 */
class TransformPosition : public QQuickItem
{
    Q_OBJECT
    QML_ELEMENT
public:
    TransformPosition();

    void init(double lat, double lng);
    double m_latitude;
    double m_longitude;
    double latitude() const;
    double longitude() const;
    void setLatitude(const double newLatitude){ m_latitude = newLatitude; };
    void setLongitude(const double newLongitude){ m_longitude = newLongitude; };

public:
    Q_PROPERTY(double latitude READ latitude WRITE setLatitude CONSTANT FINAL)
    Q_PROPERTY(double longitude READ longitude WRITE setLongitude CONSTANT FINAL)
};

#endif // TRANSFORMPOSITION_H

#include "TransformPosition.h"

TransformPosition::TransformPosition()
{

}
void TransformPosition::init(double lat, double lng)
{
    m_latitude = lat;
    m_longitude = lng;
}
double TransformPosition::longitude() const
{
    return m_longitude;
}

double TransformPosition::latitude() const
{
    return m_latitude;
}
  • 8
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值