V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
iOS 开发实用技术导航
NSHipster 中文版
http://nshipster.cn/
cocos2d 开源 2D 游戏引擎
http://www.cocos2d-iphone.org/
CocoaPods
http://cocoapods.org/
Google Analytics for Mobile 统计解决方案
http://code.google.com/mobile/analytics/
WWDC
https://developer.apple.com/wwdc/
Design Guides and Resources
https://developer.apple.com/design/
Transcripts of WWDC sessions
http://asciiwwdc.com
Cocoa with Love
http://cocoawithlove.com/
Cocoa Dev Central
http://cocoadevcentral.com/
NSHipster
http://nshipster.com/
Style Guides
Google Objective-C Style Guide
NYTimes Objective-C Style Guide
Useful Tools and Services
Charles Web Debugging Proxy
Smore
Livid
V2EX  ›  iDev

关于修正从 Core Location 获得的坐标的偏移量

  •  
  •   Livid · 2011-04-17 22:27:22 +08:00 · 25189 次点击
    这是一个创建于 4997 天前的主题,其中的信息可能已经有所发展或是发生改变。
    因为众所周知的原因,从 Core Location 获得的当前位置的坐标实际上偏移的,在把这样的坐标保存到数据库之前,必须进行偏移修正。

    貌似偏移量是一个常量,这里有人试着测量过么?
    65 条回复    1970-01-01 08:00:00 +08:00
    Livid
        1
    Livid  
    MOD
    OP
       2011-04-17 23:27:07 +08:00
    Google Earth 里对经纬度的显示,精确到六位数。
    Livid
        2
    Livid  
    MOD
    OP
       2011-04-17 23:27:51 +08:00
    -18 / +43

    接下来继续验证。
    keakon
        3
    keakon  
       2011-04-18 00:28:16 +08:00
    不是常量,各个地方都不同。

    去搜下火星坐标吧,有修正的数据库,也有人用matlab拟合了一个函数…
    jorakura
        4
    jorakura  
       2011-04-18 00:58:37 +08:00
    原来如此。不是说iOS4之后地图可以正常使用了?
    Livid
        5
    Livid  
    MOD
    OP
       2011-04-18 01:05:15 +08:00
    @jorakura Google Maps 里可以正确显示目前的所在地(那个蓝点),但是用 Core Location 取到的当前位置,如果输入到 Google Maps 里显示,就是偏移的……
    jorakura
        6
    jorakura  
       2011-04-18 01:12:04 +08:00
    太悲惨了。我刚好也在写要CoreLocation的代码。。。
    在iPhone自己的MKMapView里面对么?
    Livid
        7
    Livid  
    MOD
    OP
       2011-04-18 01:13:35 +08:00
    @jorakura MKMapView 会忠实地执行你让它画的坐标,没有偏移。

    问题在于你用 CoreLocation 取得的 current CLLocation 是需要修正的。
    summic
        8
    summic  
       2011-04-18 01:15:18 +08:00
    火星座标竟然是用来保护国家安全的,太弱智了吧?
    jorakura
        9
    jorakura  
       2011-04-18 01:17:17 +08:00
    @Livid 就是说CoreLocation的坐标是对的,地图是已经偏移过的,需要转化为火星坐标才能正确在火星地图上显示?
    lianghai
        10
    lianghai  
       2011-04-18 01:22:00 +08:00 via iPhone
    难道是 iOS 里有自己私有的修正过程?
    Sai
        11
    Sai  
       2011-04-18 01:23:00 +08:00
    @lianghai iOS自己肯定修过了。

    @jorakura @Livid 之前 Cydia 有一个修偏移的补丁,说不定可以用上。
    Livid
        12
    Livid  
    MOD
    OP
       2011-04-18 01:23:08 +08:00
    @jorakura CoreLocation 取到的坐标是错的。地图没偏。
    Livid
        13
    Livid  
    MOD
    OP
       2011-04-18 01:24:00 +08:00
    @Sai iOS 里的 Maps 应用自己做了修正。但是提供给开发者的 API 是悲剧。
    Livid
        14
    Livid  
    MOD
    OP
       2011-04-18 01:25:37 +08:00
    这个问题值得花时间研究研究。到底是 API 给出的当前位置是错的,还是地图本身是错的。

    从我目前的测试来看,地图没错,错的是 API 返回的当前位置。
    Livid
        15
    Livid  
    MOD
    OP
       2011-04-18 01:27:14 +08:00
    话说 iPhone 其实就是一个 programmable GPS,可以玩的花样太多了。。。
    jorakura
        16
    jorakura  
       2011-04-18 01:29:02 +08:00
    @Livid 4sq这些需要地图的app标识的位置也错么?好像喜欢的人挺多,是习惯了就好了的关系?
    lianghai
        17
    lianghai  
       2011-04-18 01:29:04 +08:00 via iPhone
    查了一下介绍,真是大开眼界。
    Livid
        18
    Livid  
    MOD
    OP
       2011-04-18 01:31:17 +08:00
    @jorakura 4SQ 和 GOWALLA 都是让用户从列表中选择一个附近已经存在的地名,没有用到精确定位。

    如果是需要更精确定位的应用,那么这些问题就不是小问题了。
    jorakura
        19
    jorakura  
       2011-04-18 01:31:23 +08:00
    @Livid 按理说GPS的结果来自天上的卫星。。。
    Livid
        20
    Livid  
    MOD
    OP
       2011-04-18 01:32:31 +08:00
    @jorakura 卫星 -> iOS -> CoreLocation -> User Programs

    中间还是有太多层级了。。。
    lianghai
        21
    lianghai  
       2011-04-18 01:36:30 +08:00 via iPhone
    这么说,行货和水货 GPS 得到的位置坐标是不一样的啊……
    zhuang
        22
    zhuang  
       2011-04-18 04:01:39 +08:00 via iPhone
    iphone 销往中国的版本和全世界其他地区的版本有个很大的不同,中国版的在显示国外地区的时候也只有中文数据。所以我理解问题出在地图程序上。
    地图偏移算法是非线性的,不知道算法的情况下没有太好的解决办法。
    gps 接收回来的数据可以认为是准确的,记作A,要在内置地图程序上显示,要么通过偏移算法得到偏移坐标B,要么显示的时候地图针对A 所在区域进行逆偏移操作。
    考虑到实现的简洁,还有地图更新的需要,加上国行iphone 的特殊性,很可能是生成了数据B,这样视觉上错误坐标和错误地图也能正确对应。
    至于CoreLocation 部分返回的数据,国外的机器一定是A,但国内的就不好说是A还是B了。
    nickcheng
        23
    nickcheng  
       2011-04-18 10:24:22 +08:00
    之前看到过有完美解决方法, 似乎是google提供了偏移查询借口, 不过现在文章已经被屏蔽了.

    可以在google里搜索一下如下link, 然后翻墙看cache
    http://blog.csdn.net/dongmeng110
    dismory
        24
    dismory  
       2011-04-18 10:34:40 +08:00 via iPhone
    Cydia 里有个国人开发的地图偏移修正补丁。

    我是国行 iPhone4,在 4.1 时北京的地图不需修正,武汉青岛需要修正,能够达到蓝色点位置准确,且卫星和普通地图重合。

    升级 4.3.1 后,我在北京青岛不需要修正了,武汉还没回过,不清楚。
    virushuo
        25
    virushuo  
       2011-04-18 10:39:26 +08:00
    其实这算法基本被人们反向出来了,不过你要公布出来大概就要被跨省了。
    9hills
        26
    9hills  
       2011-04-18 12:17:11 +08:00
    如@virushuo所说,该算法大家可以去搜一搜,比较简单的,但肯定不是线性偏移。。

    但注意不要发布出来,因为这个算法是国家机密,泄漏国家机密违法阿

    (其实你在程序里用了该算法就已经涉嫌泄密了。。不过貌似没人查,但到你什么时候被人找罪名的时候,这个理由比起神马“经济问题”要好用多了。。)
    leben
        27
    leben  
       2011-04-18 13:28:26 +08:00
    这个偏移好像不全是iphone的api问题,google map也有可能存在问题。在google map中定位正确并不代表在google map api中也能定位正确。我感觉Google map在国内好像经过修改。同样iphone的gps可能也经过了修改,两者作用,很难找出来一个切实有效的办法进行修正。

    目前网上是修正应用应该是是通过一个比较大的样本分析出来的偏移算法,但是具体到某一个地点的时候很可能发生错误。我们进行过一些测试,使用偏移算法之后,在一公里范围内,也不时的会发生偏移的问题,不是每次都起作用。

    我们后来实在没办法取消了gps定位功能,类4sq的服务对gps的要求并不是很高,只要能在地图上标记地点就ok了。如果是像layer这种ar应用在国内会很悲剧~~~
    Kenyth
        28
    Kenyth  
       2011-04-18 13:30:08 +08:00
    最近也碰到类似的问题。

    真不明白,这样保护国家机密除了让民间应用不方便还有什么用处,而且是只让中国人不知道国家机密,中国以外可以知道。中国很多“机密”都是这样被保护的。
    9hills
        29
    9hills  
       2011-04-18 13:52:20 +08:00
    @leben 偏移要地图和gps厂商都要做
    火星地图+火星GPS结合后应该就没有问题了。。

    以google地图为例
    ditu.google.com的地形图和卫星图均作了GPS偏移,配合偏移后的GPS信息,可以正常使用
    maps.google.com的地形图作了GPS偏移,但卫星图没有做。

    以前做过一个GPS追踪器,因为直接接收的卫星信号,所以是真实的GPS坐标,不管是和谷歌地图也好,还是百度地图也好,都偏200m以上。。无解啊无解,后来只能用Google maps的卫星图凑合了,
    raptium
        30
    raptium  
       2011-04-18 13:54:06 +08:00
    如果仅仅是地图程序做了修正 但是 CoreLocation API 返回的没有修正的话
    那么 safari 里面的 maps.google.com 就应该定位不准确了吧?
    可以试验验证一下 当然也有可能国行版的 Safari 也加了修正
    ===========
    另外提供多一点试验结果 也许有助于推理
    我用的是 国行 3GS 在香港定位
    不管是 内置的 Maps.app 还是 在 Safari 中打开 maps.google.com
    蓝点定位都很准确 误差在30米之内 且卫星图和普通地图重合
    Maps.app 的地图是简体中文 即使我把手机的语言设置成了英文
    maps.google.com 的地图是繁体中文 按说这个没有可能是修改版本了吧
    9hills
        31
    9hills  
       2011-04-18 14:03:02 +08:00
    @raptium 香港不适用于偏移。。

    所有机构发行的香港地图和所有GPS设备,在香港地区都是不会加人为偏移的
    想偏还没法偏呢。

    另外GPS精度确实就是在20m左右--
    raptium
        32
    raptium  
       2011-04-18 14:09:43 +08:00
    @9hills
    问题是我用的国行 iPhone 如果是国行的机器做了手脚 那应该在国内定位准在国外定位不准才对
    难道还有算法检测在不在境内的?
    换句话说 是不是水货 iPhone 的 Maps.app 在国内定位会偏移呢?
    Livid
        33
    Livid  
    MOD
    OP
       2011-04-18 15:20:23 +08:00
    @raptium Maps 在国内使用起来没有任何问题(起码在上海是这样),问题在于 CoreLocation 返回的坐标。
    9hills
        34
    9hills  
       2011-04-18 16:36:21 +08:00
    @raptium 那个地图偏移算法只对大陆地区有效的,国行的机器在国外定位很准

    再说一次,这个偏移并不是那种所有的点统一偏移的,而是只针对大陆境内的随机偏移
    aligo
        35
    aligo  
       2011-04-18 17:06:04 +08:00
    是地图有偏移,Core Location获取的坐标才是正确的

    ditu.google.cn提供了一个api用来转换这个,但是由于众所周知的原因受到限制,这里贴一个百度的地址: http://hi.baidu.com/ray_li/blog/item/3fa0850542709ac67a894747.html ,api地址:
    http://ditu.google.cn/maps/vp?spn=0.0,0.0&z=18&vp=39.111195,117.148067

    现在我有一个15万行左右的,储存火星坐标匹配地球坐标数据库,大小是7.1MB,一般用它直接取中点的方法得出一个大概坐标,这是目前比较靠谱的解决方法了

    具体火星坐标的真正算法不明,花时间用matlab暴力破解也只是大概能用,同过调试方法破解这个东西的机会也不大,国内那些导航软件没有一个提供具体坐标输入或者显示的,而google能做的最过分的就是提供上面那个api了

    当然破解它的可能性还是有的,关键是会不会被抓起来神马的。。。
    aligo
        36
    aligo  
       2011-04-18 17:17:05 +08:00
    我知道的,例如这个玩意,就是用了数据库大法转换火星坐标的

    http://itunes.apple.com/cn/app/global-navigator/id402174308
    Livid
        37
    Livid  
    MOD
    OP
       2011-04-18 17:21:55 +08:00
    @aligo 我刚才试验了一下,用 CoreLocation 获得的坐标,输入进 Google Earth,确实是准的。

    但是这些坐标如果和 MKMapView 配合,显示给最终用户的话,作为视觉上的结果,就是偏移的。。。所以,确实是地图有偏移。

    这个问题需要做一个取舍。。。我得好好想想。。。
    aligo
        38
    aligo  
       2011-04-18 17:26:33 +08:00
    @Livid 如果是一次性求坐标而且有网络环境就用ditu.google.cn的那个api吧

    如果客户端频繁离线使用只能用数据库大法,压缩一下还是控制住大小,但是对移动设备检索可能会有一点压力
    Livid
        39
    Livid  
    MOD
    OP
       2011-04-18 17:30:14 +08:00
    @aligo 所以,目前阶段性的一个总结:

    CoreLocation -> 准确
    Google Earth -> 准确
    MKMapView -> 偏移

    Possible Solution:

    * 数据库中存储原始的坐标值
    * 在所有的 API 里也使用原始的坐标值
    * 当需要在 MKMapView 或是 Google Static Maps 里显示时,进行纠偏

    是这样么?
    aligo
        40
    aligo  
       2011-04-18 17:46:01 +08:00
    @Lividhttp://ditu.google.cn/http://maps.google.com/ 分别输入39.907001,116.391001,绿色箭头,后者准确的落在天安门上,前者偏移到了北京一六一中学对面(偏移到平民目标真是恶趣味啊)

    而39.907001,116.391001才是真正的GPS测得的坐标,可见 http://ditu.google.cn/ 的地图使用的就是加密的火星坐标系统

    然后还有一个判断基站提供的AGPS数据的问题,是否也是国内的火星坐标系统,如果是的话,那么也许可以绑架一台基站对其进行反向工程XD

    还有一种情况,可能国内最新使用的民用GPS导航设备的硬件芯片都被要求进行火星坐标加密,只能输出火星坐标(可能性不大)
    aligo
        41
    aligo  
       2011-04-18 17:47:13 +08:00
    @Livid 你可以先试试39.907001,116.391001这个坐标在MKMapView中是否正常,是否所有的语言、固件、位置设置的设备都是如此
    9hills
        42
    9hills  
       2011-04-18 19:06:14 +08:00
    @aligo AGPS和民用GPS芯片 使用火星坐标的可能性都不大
    icyleaf
        43
    icyleaf  
       2011-04-25 00:00:12 +08:00
    @Livid Google 有提供一个 API 接口,看看这个: http://blog.sina.com.cn/s/blog_65bd7eef0100hu5o.html
    ccp0101
        44
    ccp0101  
       2011-05-11 14:16:46 +08:00   ❤️ 2
    找到Apple内部对MKUserLocation去除偏移的方法。

    [MKLocationManager _applyChinaLocationShift:(CLLocation*)arg]

    这个方法返回去除偏移后的CLLocation*。


    Code:


    @interface MKLocationManager
    - (CLLocation*)_applyChinaLocationShift:(CLLocation*)arg;
    - (BOOL)chinaShiftEnabled;
    + (id)sharedLocationManager;
    @end

    CLLocationManager's Delegate:

    - (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation
    {
    if ([[MKLocationManager sharedLocationManager] chinaShiftEnabled]) {
    newLocation = [[MKLocationManager sharedLocationManager] _applyChinaLocationShift:newLocation];
    if (newLocation == nil) return;
    }
    }
    Livid
        45
    Livid  
    MOD
    OP
       2011-05-11 14:22:41 +08:00
    @ccp0101 非常感谢你的分享。
    Kai
        46
    Kai  
    MOD
       2011-05-11 14:38:56 +08:00
    chinaShiftEnabled...

    这个,太威武了
    ccp0101
        47
    ccp0101  
       2011-05-12 17:50:09 +08:00   ❤️ 1
    应该研究下_applyChinaShift:这个method是不是用得google的偏移服务。我看了dump的header看到有GMMRequest但是不确定是否调用了那个google的web接口。但是这个method返回的时候不block的所以不排除内部实现了反偏移算法。我抓包也没有看到http明文(非https)调用那个接口。
    levey
        48
    levey  
       2011-11-27 10:36:21 +08:00
    @ccp0101 谢谢分享。
    freewizard
        49
    freewizard  
       2011-11-27 13:47:11 +08:00
    iOS5开始不再使用[MKLocationManager _applyChinaLocationShift:],改用GEOLocationShiftProvider类了
    keakon
        50
    keakon  
       2011-11-27 16:30:53 +08:00
    @freewizard GEOLocationShiftProvider是什么?Google找不到任何资料…
    tokki
        51
    tokki  
       2011-11-28 10:42:43 +08:00
    好吧 过几天也要高这些东西 原来这里面这么多文章啊
    kangxy
        52
    kangxy  
       2011-11-28 17:02:20 +08:00
    @Kenyth 收钱,有服务器license和客户端license,不交钱就是泄露国家机密.
    kakashilw
        53
    kakashilw  
       2011-12-20 18:11:09 +08:00
    最近要做个AR的应用,这个偏移量特别头疼。。。在距离比较近的时候,会造成很大误差~~
    allanpk716
        54
    allanpk716  
       2012-02-23 21:52:25 +08:00
    表示dump了有关location的东西,搜索了下也没看到GEOLocationShiftProvider这个东西啊,而且google都是果然在谈论,有点邪乎了把。
    dump出来的确有GEOLocationShift关键字倒是,不过反正是弄越狱开发,去t的apple认证。^-^
    allanpk716
        55
    allanpk716  
       2012-02-23 21:53:26 +08:00
    打字快了···国人···不是果然
    allanpk716
        56
    allanpk716  
       2012-02-25 12:53:19 +08:00
    IOS 5的解决方案有了,个人测试OK,而且估计通用,请跳转下。
    http://blog.sina.com.cn/s/blog_5d34020101013525.html
    dazuiba
        57
    dazuiba  
       2012-03-17 12:08:58 +08:00
    调用applyChinaLocationShift 会影响审核么?

    @allanpk716 MKMapview自己的userLocation是没有偏移的.

    这就解释了一个现象:MKMapview的showsUserLocation打开后, 地图上会多出一个蓝点,代表当前位置----这个蓝点是没有偏移的.

    用这个userLocation绝对是ok的, 但是就依赖了MKMapView, 我的App给用户展示的是列表模式, 一开始不打开MKMapview的..
    allanpk716
        58
    allanpk716  
       2012-04-10 19:06:48 +08:00
    @dazuiba 印象public是没得的,我都是dump private的用的,也有可能我记错了。

    applyChinaLocationShift 这个在IOS 4.33上测试是可以用的,IOS 5不行,其实变向使用mapkit来解决通用性强。

    MKMapview 这个其实你创建一个实例就好了,也就是不要拖控件,直接代码做,我做的娱乐插件都是后台的,不需要用户看到的。
    Smartype
        59
    Smartype  
       2012-04-25 16:34:33 +08:00   ❤️ 1
    Google Mobile Maps 使用的是 ProtocolBuffers.
    GMM 提供一个 China Location Shift 的服务。提交一个 MapPoint 到 GMM 可以返回一个5个系数。两个区域大小值。通过比较想要修正点和这两个区域值。确定该修正系数是否适用。否则就得请求新的系数。
    具体的偏移获取协议以及修正算法可以逆向 GMM.framework。怕被喝茶,所以不提供太多细节。
    所以适用数据库做法是很傻的。如果把这个系数库爬出来。似乎也不错。呵呵。不想再折腾了。
    Smartype
        60
    Smartype  
       2012-04-25 16:35:25 +08:00
    不好意思,是6个系数。修正经度,纬度各用三个。
    pythons
        61
    pythons  
       2012-08-05 10:35:58 +08:00   ❤️ 1
    一种是调用私有类MKLocationManager的_applyChinaLocationShift方法计算偏移后的坐标,还有一种是使用-(void)mapView:(MKMapView *)mapView didUpdateUserLocation:(MKUserLocation *)userLocation 该事件中的坐标是正确的。
    Smartype
        62
    Smartype  
       2012-08-07 09:50:12 +08:00
    @pythons 你那个前提得让MapView显示当前位置,它才会request 当前位置的 shift function, 你才有东西可以apply
    donbe
        63
    donbe  
       2012-08-07 10:00:42 +08:00
    @ccp0101 ios里抓包app是哪个?
    pythons
        64
    pythons  
       2012-12-18 15:58:27 +08:00
    @Smartype MapView 你可以 hidden 嘛.
    coolypf
        65
    coolypf  
       2013-02-03 18:06:16 +08:00
    地球坐标系 (WGS-84) 到火星坐标系的转换算法
    http://blog.csdn.net/coolypf
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2964 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 30ms · UTC 13:16 · PVG 21:16 · LAX 05:16 · JFK 08:16
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.