解决iOS开发MapKit定位的经纬度和地图显示经纬度对不上的问题

在iOS开发中,使用MapKit进行地图显示和定位是非常常见的需求。然而,有时候我们会发现定位获取的经纬度和地图显示的经纬度不一致,导致显示的位置和实际位置有偏差。这个问题可能是由于坐标系不同或者坐标转换错误导致的。本文将介绍如何解决这个问题,并提供代码示例。

问题分析

iOS开发中,MapKit使用的是WGS-84坐标系,而有些地图服务商使用的是GCJ-02坐标系(火星坐标系),这两种坐标系之间存在一定的偏移,导致经纬度对不上。因此,我们在获取定位信息后,需要将其转换为WGS-84坐标系才能正确显示在MapKit上。

解决方法

我们可以使用第三方库来进行坐标系的转换,其中比较常用的是CLLocation+ChinaMapOffset这个库。该库可以将GCJ-02坐标系转换为WGS-84坐标系,从而解决定位经纬度和地图显示经纬度对不上的问题。

下面是一个简单的示例代码,演示如何使用CLLocation+ChinaMapOffset库来进行坐标系的转换:

import CoreLocation

extension CLLocation {
    
    func chinaOffset() -> CLLocation {
        let a = 6378245.0
        let ee = 0.00669342162296594323
        let dLat = transformLatWith(x: longitude - 105.0, y: latitude - 35.0)
        let dLon = transformLonWith(x: longitude - 105.0, y: latitude - 35.0)
        let radLat = latitude / 180.0 * Double.pi
        var magic = sin(radLat)
        magic = 1 - ee * magic * magic
        let sqrtMagic = sqrt(magic)
        dLat = (dLat * 180.0) / ((a * (1 - ee)) / (magic * sqrtMagic) * Double.pi)
        dLon = (dLon * 180.0) / (a / sqrtMagic * cos(radLat) * Double.pi)
        return CLLocation(latitude: latitude - dLat, longitude: longitude - dLon)
    }
    
    func transformLatWith(x: Double, y: Double) -> Double {
        var 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 * Double.pi) + 20.0 * sin(2.0 * x * Double.pi)) * 2.0 / 3.0
        ret += (20.0 * sin(y * Double.pi) + 40.0 * sin(y / 3.0 * Double.pi)) * 2.0 / 3.0
        ret += (160.0 * sin(y / 12.0 * Double.pi) + 320 * sin(y * Double.pi / 30.0)) * 2.0 / 3.0
        return ret
    }
    
    func transformLonWith(x: Double, y: Double) -> Double {
        var 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 * Double.pi) + 20.0 * sin(2.0 * x * Double.pi)) * 2.0 / 3.0
        ret += (20.0 * sin(x * Double.pi) + 40.0 * sin(x / 3.0 * Double.pi)) * 2.0 / 3.0
        ret += (150.0 * sin(x / 12.0 * Double.pi) + 300.0 * sin(x / 30.0 * Double.pi)) * 2.0 / 3.0
        return ret
    }
}

以上代码中,我们扩展了CLLocation类,添加了chinaOffset方法来进行坐标系转换,从而解决经纬度不一致的问题。

示例

接下来,我们将演示如何使用CLLocation+ChinaMapOffset库来解决