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;
}
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;
}
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>
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
#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;
}