真实GPS坐标信息转百度地图坐标

      第一次写博客,记录自己成长的过程。如有是错误的地方,请大家提出。

      做了一个小的项目,遇到通过模块获得的真实的GPS信息,需要转换到百度地图上显示。后来在网上查阅,

    真实标准坐标即我们获取到的坐标,真实坐标经经过国家测绘局进行加密后形成火星坐标(WGS-84 ),百度地图,在火星坐标的基础上再进行一次加密,形成了百度地图上的坐标,因此,直接将标准地球坐标显示在百度地图上是会有几百米的偏差的。按照此原理,标准GPS坐标经过两步的转换可得到百度坐标。

     当然可以直接使用百度开放的API http://lbsyun.baidu.com/index.php?title=webapi/guide/changeposition  

但是在有一些的开发中不需要进行API的调用。这时就需要用到自己的函数转化。

以下是全部函数源码。(来自于一名网友,我分享大家http://bbs.lbsyun.baidu.com/forum.php?mod=viewthread&tid=10923)

以下是我自己搬运后的C代码,已在stm32上实现。百度地图定位显示精度5m以内。


在此感谢我的学长zjk


//以下是偏移到百度地图的算法
static double pi = 3.14159265358979324;      //圆周率
static double ee = 0.00669342162296594323;   //椭球的偏心率
static double a = 6378245.0;                 //卫星椭球坐标投影到平面地图坐标系的投影因子
static double x_pi = 3.14159265358979324 * 3000.0 / 180.0;  //圆周率转换量


// 求弧度
double radian(double d)
{
    return d * pi / 180.0;   //角度1? = π / 180
}
 

double transformLat(double lat, double lon)    //纬度转化
{
	 double ret = -100.0 + 2.0 * lat + 3.0 * lon + 0.2 * lon * lon + 0.1 * lat * lon + 0.2 * sqrt(abs(lat));
   ret += (20.0 * sin(6.0 * lat * pi) + 20.0 * sin(2.0 * lat * pi)) * 2.0 / 3.0;
   ret += (20.0 * sin(lon * pi) + 40.0 * sin(lon / 3.0 * pi)) * 2.0 / 3.0;
   ret += (160.0 * sin(lon / 12.0 * pi) + 320 * sin(lon * pi  / 30.0)) * 2.0 / 3.0;
   return ret;
}


double transformLon(double lat,double lon)   //经度转化
{
	 double ret = 300.0 + lat + 2.0 * lon + 0.1 * lat * lat + 0.1 * lat * lon + 0.1 * sqrt(abs(lat));
   ret += (20.0 * sin(6.0 * lat * pi) + 20.0 * sin(2.0 * lat * pi)) * 2.0 / 3.0;
   ret += (20.0 * sin(lat * pi) + 40.0 * sin(lat / 3.0 * pi)) * 2.0 / 3.0;
   ret += (150.0 * sin(lat / 12.0 * pi) + 300.0 * sin(lat / 30.0 * pi)) * 2.0 / 3.0;
   return ret;
}


/*****************************************************************************
 * WGS84(GPS坐标系) to 火星坐标系(GCJ-02)
 * 
 * @param lat
 * @param lon
 * @return
 ****************************************************************************/
void GPS84_To_GCJ02(double WGS84_Lat, double WGS84_Lon,double * GCJ02_Lat, double * GCJ02_Lon)
{
	double dLat;
	double dLon;
	double radLat;
	double magic;
	double sqrtMagic;

	dLat = transformLat(WGS84_Lon - 105.0, WGS84_Lat - 35.0);
	dLon = transformLon(WGS84_Lon - 105.0, WGS84_Lat - 35.0);
	radLat = WGS84_Lat / 180.0 * pi;
	magic = sin(radLat);
	magic = 1 - ee * magic * magic;
	sqrtMagic = sqrt(magic);
	dLat = (dLat * 180.0) / ((a * (1 - ee)) / (magic * sqrtMagic) * pi);
	dLon = (dLon * 180.0) / (a / sqrtMagic * cos(radLat) * pi);
	*GCJ02_Lat = WGS84_Lat + dLat;    //GCJ02_Lat是百度纬度存储变量的地址  *GCJ02_Lat就是那个值
	*GCJ02_Lon = WGS84_Lon + dLon;    //GCJ02_Lon是百度经度存储变量的地址  *GCJ02_Lon
}

/*****************************************
 * 火星坐标系 (GCJ-02) 与百度坐标系 (BD-09) 的转换算法 将 GCJ-02 坐标转换成 BD-09 坐标
 * 
 * @param gg_lat
 * @param gg_lon
 *****************************************/
//传入的参数  	GCJ02_To_BD09(*BD09_Lat,*BD09_Lon,BD09_Lat,BD09_Lon);
//(*BD09_Lat,*BD09_Lon)火星坐标,(BD09_Lat,BD09_Lon)是变量的地址
void GCJ02_To_BD09(double GCJ02_Lat,double GCJ02_Lon,double * BD_09_Lat,double * BD_09_Lon)
{
		double x = GCJ02_Lon, y = GCJ02_Lat;
	  double z= sqrt(x * x + y * y) + 0.00002 * sin(y * x_pi);
	  double theta =atan2(y, x) + 0.000003 * cos(x * x_pi);
	  *BD_09_Lon = z * cos(theta) + 0.0065;
	  *BD_09_Lat = z * sin(theta) + 0.006;
}


/*************************************************************
函数名称:GPS_transformation(double WGS84_Lat, double WGS84_Lon,double * BD_09_Lat, double * BD_09_Lon)
函数功能:GPS坐标转百度地图坐标
输入参数:WGS84_Lat,WGS84_Lon GPS获取到真实经纬度  储存得到的百度经纬度变量的地址 BD_09_Lat,BD_09_Lon指向那个变量
输出参数:
*************************************************************/ 
void GPS_transformation(double WGS84_Lat,double WGS84_Lon,double * BD_09_Lat,double * BD_09_Lon)
{
	 GPS84_To_GCJ02(WGS84_Lat,WGS84_Lon,BD_09_Lat,BD_09_Lon);           //GPS坐标转火星坐标
	 GCJ02_To_BD09(*BD_09_Lat,*BD_09_Lon,BD_09_Lat,BD_09_Lon);           //火星坐标转百度坐标 
}

/*************************************************************
函数名称:double GetDistance(double lat1, double lng1, double lat2, double lng2)
函数功能:返回两个点之间的距离
输入参数:两个点的经纬度(角度)
输出参数:距离(单位:km)
*************************************************************/ 
double Cal_Distance(double lat1, double lng1, double lat2, double lng2)
{
	  double EARTH_RADIUS = 6378.137;        //地球近似半径
    double radLat1 = radian(lat1);
    double radLat2 = radian(lat2);
    double a = radLat1 - radLat2;
    double b = radian(lng1) - radian(lng2);
     
    double dst = 2 * asin((sqrt(pow(sin(a / 2), 2) + cos(radLat1) * cos(radLat2) * pow(sin(b / 2), 2) )));    //asin()反正弦值函数
     
    dst = dst * EARTH_RADIUS;
    dst= (u32)(dst * 10000.0) / 10000.0;//舍弃小数点后4位的数
    return dst;
}

     为大家附上的到百度坐标后,在地图上显示http://api.map.baidu.com/lbsapi/getpoint/index.html  输入经纬度,点上坐标反查即可。

最后附上我测试的截图




你可能感兴趣的:(嵌入式)