WGS-84与GCJ-02(高德)转换

特性WGS-84GCJ-02(国测局坐标系)
性质全球标准地理坐标系中国官方加密偏移坐标系
制定方美国国防部(1984年确立)中国国家测绘地理信息局(2002年推出)
定位精度真实地球坐标(GPS卫星原始数据)在WGS-84基础上人为加入随机偏移
法律地位国际通用标准(谷歌地图、苹果地图境外使用)中国法定地图服务坐标系(高德、腾讯、百度境内使用)
偏移目的无偏移(科学测量基准)国家安全(防止高精度坐标被军事利用)
#ifndef QGCTRANSFORM_H
#define QGCTRANSFORM_H
#include <QPointF>
#include <QtMath>

class QGCTransform
{
private:
	// 克拉索夫斯基椭球参数
	static constexpr const double a = 6378245.0;              // 长半轴
	static constexpr const double ee = 0.00669342162296594323; // 扁率
	//判断是否在国内,不在国内则不做偏移
	static bool outOfChina(double lat, double lon);
	//度分格式转十进制度
	static double dmToDegrees(double dm);
	//纬度偏移计算
	static double transformLat(double x, double y);
	//经度偏移计算
    static double transformLon(double x, double y);
public:
	//wgs84转gcj02 返回lng,lat
	static QPointF wgs84Togcj02(double wgsLat, double wgsLon);
};

#endif 

#include "QGCTransform.h"
// 类外定义静态常量(C++11标准要求)
constexpr double QGCTransform::a;
constexpr double QGCTransform::ee;

bool QGCTransform::outOfChina(double lat, double lon)
{
	if (lon < 72.004 || lon > 137.8347) return true;
	if (lat < 0.8293 || lat > 55.8271) return true;
	return false;
}

double QGCTransform::dmToDegrees(double dm)
{
	// 分离度和分
	int degrees = static_cast<int>(dm / 100);
	double minutes = dm - degrees * 100;
	// 转换公式:十进制度 = 度 + 分/60
	return degrees + minutes / 60.0;
}

double QGCTransform::transformLat(double x, double y)
{
	double ret = -100.0 + 2.0 * x + 3.0 * y + 0.2 * y * y +
		0.1 * x * y + 0.2 * sqrt(fabs(x));
	ret += (20.0 * sin(6.0 * x * M_PI) + 20.0 * sin(2.0 * x * M_PI)) * 2.0 / 3.0;
	ret += (20.0 * sin(y * M_PI) + 40.0 * sin(y / 3.0 * M_PI)) * 2.0 / 3.0;
	ret += (160.0 * sin(y / 12.0 * M_PI) + 320 * sin(y * M_PI / 30.0)) * 2.0 / 3.0;
	return ret;
}

double QGCTransform::transformLon(double x, double y)
{
	double ret = 300.0 + x + 2.0 * y + 0.1 * x * x +
		0.1 * x * y + 0.1 * sqrt(fabs(x));
	ret += (20.0 * sin(6.0 * x * M_PI) + 20.0 * sin(2.0 * x * M_PI)) * 2.0 / 3.0;
	ret += (20.0 * sin(x * M_PI) + 40.0 * sin(x / 3.0 * M_PI)) * 2.0 / 3.0;
	ret += (150.0 * sin(x / 12.0 * M_PI) + 300.0 * sin(x / 30.0 * M_PI)) * 2.0 / 3.0;
	return ret;
}

QPointF QGCTransform::wgs84Togcj02(double wgsLat, double wgsLon)
{
	double wgsLat1 = dmToDegrees(wgsLat);
	double wgsLon1 = dmToDegrees(wgsLon);
	if (outOfChina(wgsLat1, wgsLon1)) 
	{
		return QPointF(wgsLon1, wgsLat1);
	}

	double dLat = transformLat(wgsLon1 - 105.0, wgsLat1 - 35.0);
	double dLon = transformLon(wgsLon1 - 105.0, wgsLat1 - 35.0);

	const double radLat = wgsLat1 / 180.0 * M_PI;
	double magic = sin(radLat);
	magic = 1 - ee * magic * magic;

	const double sqrtMagic = sqrt(magic);
	dLat = (dLat * 180.0) / ((a * (1 - ee)) / (magic * sqrtMagic) * M_PI);
	dLon = (dLon * 180.0) / (a / sqrtMagic * cos(radLat) * M_PI);

	return QPointF(wgsLon1 + dLon, wgsLat1 + dLat);
}

目前测试下来是可以使用的,我的配置环境是VS2022+QT5.15.2

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值