1. 程式人生 > >GPS定位不準確、有偏差的問題

GPS定位不準確、有偏差的問題

GPS型號:SIMCOM7100C

最近在做gps定位這塊,發現經緯度定位並不準確,偏差的有點離譜。網上查了好多資料,各種座標系之間相互轉換。

在地圖上輸入轉換後的經緯度,偏的不是一點半點。


後來發現是轉換前的資料來源需要轉換。

這是從gps模組獲取到的源資料,它是屬於地球座標系的

+CGPSINFO: 3958.472727,N,11619.957711,E,140416,020450.0,77.6,0.0,181.0


 

它表示北緯39度58.472727分,東經116度19.957711分 這種格式並不是常見的那種度、分、秒也不是小數度數。它是度十進位制分!!!

需要轉換為小數度數才能進行地球座標轉火星座標

轉換方法很簡單 如上3958.472727 轉換為 39°+58.472727/60=39.97454545°

然後就可以用它來進行轉換了。

轉換 演算法如下:

#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>
#include <termios.h>
#include <errno.h>
#include <sys/ioctl.h>
#include <stdlib.h>
#include <math.h>
#include <stdbool.h>





static double x_pi = 3.14159265358979324 * 3000.0 / 180.0;




//高德轉百度
static int bd_encrypt(double gg_lat, double gg_lon, double *bd_lat,
                      double *bd_lon)
{


    double x = gg_lon, y = gg_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_lon = z * cos(theta) + 0.0065;
    *bd_lat = z * sin(theta) + 0.006;
    return 0;


}


// 百度轉高德
static void bd_decrypt(double bd_lat, double bd_lon, double *gg_lat,
                       double *gg_lon)
{
    double x = bd_lon - 0.0065, y = bd_lat - 0.006;
    double z = sqrt(x * x + y * y) - 0.00002 * sin(y * x_pi);
    double theta = atan2(y, x) - 0.000003 * cos(x * x_pi);


    *gg_lon = z * cos(theta);
    *gg_lat = z * sin(theta);


}


static double 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(abs(x));
    ret += (20.0 * sin(6.0 * x * PI) + 20.0 * sin(2.0 * x * PI)) * 2.0 / 3.0;
    ret += (20.0 * sin(y * PI) + 40.0 * sin(y / 3.0 * PI)) * 2.0 / 3.0;
    ret += (160.0 * sin(y / 12.0 * PI) + 320 * sin(y * PI / 30.0)) * 2.0 / 3.0;
    return ret;
}


static double transformlon(double x, double y)
{
    double ret =
        300.0 + x + 2.0 * y + 0.1 * x * x + 0.1 * x * y + 0.1 * sqrt(abs(x));
    ret += (20.0 * sin(6.0 * x * PI) + 20.0 * sin(2.0 * x * PI)) * 2.0 / 3.0;
    ret += (20.0 * sin(x * PI) + 40.0 * sin(x / 3.0 * PI)) * 2.0 / 3.0;
    ret +=
        (150.0 * sin(x / 12.0 * PI) + 300.0 * sin(x / 30.0 * PI)) * 2.0 / 3.0;
    return ret;
}


// GPS轉高德(火星座標系) 
int transform(double wglat, double wglon, double *mglat, double *mglon)
{
    const double a = 6378245.0;
    const double ee = 0.00669342162296594323;


    double dlat = transformlat(wglon - 105.0, wglat - 35.0);
    double dlon = transformlon(wglon - 105.0, wglat - 35.0);
    double radlat = wglat / 180.0 * PI;
    double magic = sin(radlat);


    magic = 1 - ee * magic * magic;
    double sqrtmagic = sqrt(magic);


    dlat = (dlat * 180.0) / ((a * (1 - ee)) / (magic * sqrtmagic) * PI);
    dlon = (dlon * 180.0) / (a / sqrtmagic * cos(radlat) * PI);
    *mglat = wglat + dlat;
    *mglon = wglon + dlon;
    return 0;
}

轉完之後就可以在地圖上輸入經緯度定位了,另外編譯的時候需要加上 -lm引數。測試誤差基本在十米之內。前提是你獲取到的GPS資料是準確的。怎麼確定是否準確呢,可以同步谷歌地球(很吊的軟體)來確定。

1、選擇工具、進入選項介面



2、設定為度十進位制分


3、點選新增地標選項


輸入經緯度


4、雙擊我的地點,就定位到了