app 地圖 定位填坑

最近在做一個(gè)地圖定位的功能,遇到一個(gè)問(wèn)題:就是定位的坐標(biāo)始終有偏差大概幾百米距離。
查閱資料了解到是坐標(biāo)系問(wèn)題。目前常見(jiàn)的坐標(biāo)系有三種:地球坐標(biāo)(WGS84,國(guó)際公認(rèn)坐標(biāo)),火星坐標(biāo)(GCJ02,國(guó)家標(biāo)準(zhǔn),適用于高德百度地圖大陸+港澳部分、Google地圖大陸部分),百度坐標(biāo)(BD09,適用于百度地圖大陸+港澳臺(tái)部分)。坐標(biāo)系需要和地圖關(guān)連才有意義,只有正確匹配地圖坐標(biāo)系的坐標(biāo)才能在該地圖上完美標(biāo)識(shí)位置,否則就會(huì)存在偏移。
iOS系統(tǒng)上通過(guò)定位服務(wù)CLLocation相關(guān)接口獲取定位信息時(shí),獲取的經(jīng)緯度坐標(biāo)系是WGS84地球坐標(biāo),如果直接將該坐標(biāo)系在iOS系統(tǒng)地圖中打點(diǎn),會(huì)發(fā)現(xiàn)存在偏移,因?yàn)閕OS系統(tǒng)地圖查看國(guó)內(nèi)時(shí)使用的是高德地圖數(shù)據(jù),因此只接受GCJ02火星坐標(biāo)。所以如果我們是直接使用系統(tǒng)的定位服務(wù),而不是第三方SDK的話,就需要將WGS84編碼轉(zhuǎn)成GCJ02就好了

const double a = 6378245.0;
const double ee = 0.00669342162296594323;
const double pi = 3.14159265358979324;

+ (CLLocationCoordinate2D)transformFromWGSToGCJ:(CLLocationCoordinate2D)wgsLoc {
    CLLocationCoordinate2D adjustLoc;
    
    if ([self isLocationOutOfChina:wgsLoc]) {
        adjustLoc = wgsLoc;
    } else {
        double adjustLat = [self transformLatWithX:wgsLoc.longitude - 105.0 withY:wgsLoc.latitude - 35.0];
        double adjustLon = [self transformLonWithX:wgsLoc.longitude - 105.0 withY:wgsLoc.latitude - 35.0];
        double radLat = wgsLoc.latitude / 180.0 * pi;
        double magic = sin(radLat);
        magic = 1 - ee * magic * magic;
        double sqrtMagic = sqrt(magic);
        adjustLat = (adjustLat * 180.0) / ((a * (1 - ee)) / (magic * sqrtMagic) * pi);
        adjustLon = (adjustLon * 180.0) / (a / sqrtMagic * cos(radLat) * pi);
        adjustLoc.latitude = wgsLoc.latitude + adjustLat;
        adjustLoc.longitude = wgsLoc.longitude + adjustLon;
    }
    return adjustLoc;
}

// 判斷是不是在中國(guó)
+ (BOOL)isLocationOutOfChina:(CLLocationCoordinate2D)location {
    if (location.longitude < 72.004 || location.longitude > 137.8347 || location.latitude < 0.8293 || location.latitude > 55.8271) {
        return YES;
    }
    return NO;
}

+ (double)transformLatWithX:(double)x withY:(double)y {
    double lat = -100.0 + 2.0 * x + 3.0 * y + 0.2 * y * y + 0.1 * x * y + 0.2 * sqrt(fabs(x));
    lat += (20.0 * sin(6.0 * x * pi) + 20.0 *sin(2.0 * x * pi)) * 2.0 / 3.0;
    lat += (20.0 * sin(y * pi) + 40.0 * sin(y / 3.0 * pi)) * 2.0 / 3.0;
    lat += (160.0 * sin(y / 12.0 * pi) + 3320 * sin(y * pi / 30.0)) * 2.0 / 3.0;
    return lat;
}

+ (double)transformLonWithX:(double)x withY:(double)y {
    double lon = 300.0 + x + 2.0 * y + 0.1 * x * x + 0.1 * x * y + 0.1 * sqrt(fabs(x));
    lon += (20.0 * sin(6.0 * x * pi) + 20.0 * sin(2.0 * x * pi)) * 2.0 / 3.0;
    lon += (20.0 * sin(x * pi) + 40.0 * sin(x / 3.0 * pi)) * 2.0 / 3.0;
    lon += (150.0 * sin(x / 12.0 * pi) + 300.0 * sin(x / 30.0 * pi)) * 2.0 / 3.0;
    return lon;
}

參考大神文章 http://blog.csdn.net/zhengang007/article/details/52858198

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容