火星坐标 C语言,iOS7上地球坐标系到火星坐标系转换算法

2013年01月31日 ⁄ 综合 ⁄ 共 2595字 ⁄ 字号 ⁄ 评论关闭

今天在一个项目中需要用到地球坐标系到火星坐标系的转换,找了好几种实现方法,但都无法在iOS6以上的系统中使用,最后找到了一个C#的转换

目前网上的方法主要有以下几种:

1.在iOS4.3之前的系统上通过私有类MKLocationManager中的_applyChinaLocationShift来转换地球坐标到火星坐标。这种方法有两个问题,一个是调用了私有api,另一个是在iOS5之后的系统不能用了。

2.利用MKMapView中的isShowUserLocation进行定位,这种方法也有两个问题,一个是必须要创建MKMapView才行,二是无法实现后台定位。

3.利用MapABC API中的GPSToOffSetByPoint:方法进行坐标转换,本人并没有对这种方法进行尝试,因为实现起来比较麻烦,还得申请API Key。

4.对地球坐标系与火星坐标系建立一一映射关系,并将这个关系存到数据库中,通过数据库进行转换。这种方法的问题是数据库体积较大,不适用于移动客户端

5.利用高德、百度地图提供的在线api进行转换,这种方法的问题是不能离线进行转换,实用性不强。

6.利用已有的算法将地球坐标系转换到火星坐标系

转换得到的OC

const double a = 6378245.0;

const double ee = 0.00669342162296594323;

+ (CLLocation *)transformToMars:(CLLocation *)location {

//是否在中国大陆之外

if ([[self class] outOfChina:location]) {

return location;

}

double dLat = [[self class] transformLatWithX:location.coordinate.longitude - 105.0 y:location.coordinate.latitude - 35.0];

double dLon = [[self class] transformLonWithX:location.coordinate.longitude - 105.0 y:location.coordinate.latitude - 35.0];

double radLat = location.coordinate.latitude / 180.0 * M_PI;

double magic = sin(radLat);

magic = 1 - ee * magic * magic;

double sqrtMagic = sqrt(magic);

dLat = (dLat * 180.0) / ((a * (1 - ee)) / (magic * sqrtMagic) * M_PI);

dLon = (dLon * 180.0) / (a / sqrtMagic * cos(radLat) * M_PI);

return [[CLLocation alloc] initWithLatitude:location.coordinate.latitude + dLat longitude:location.coordinate.longitude + dLon];

}

+ (BOOL)outOfChina:(CLLocation *)location {

if (location.coordinate.longitude  137.8347) {

return YES;

}

if (location.coordinate.latitude  55.8271) {

return YES;

}

return NO;

}

+ (double)transformLatWithX:(double)x y:(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 * M_PI) + 20.0 * sin(2.0 * x * M_PI)) * 2.0 / 3.0;

ret += (20.0 * sin(y * M_PI) + 40.0 * sin(y / 3.0 * M_PI)) * 2.0 / 3.0;

ret += (160.0 * sin(y / 12.0 * M_PI) + 320 * sin(y * M_PI / 30.0)) * 2.0 / 3.0;

return ret;

}

+ (double)transformLonWithX:(double)x y:(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 * M_PI) + 20.0 * sin(2.0 * x * M_PI)) * 2.0 / 3.0;

ret += (20.0 * sin(x * M_PI) + 40.0 * sin(x / 3.0 * M_PI)) * 2.0 / 3.0;

ret += (150.0 * sin(x / 12.0 * M_PI) + 300.0 * sin(x / 30.0 * M_PI)) * 2.0 / 3.0;

return ret;

}

将以上代码放到任意一个类中,使用静态方法transformToMars:对地球坐标进行转换即可。

以下为最后转换的结果:

mapkit得到的坐标:40.006498, 116.328022

CLLocationManager得到的坐标:40.005196, 116.321890

算法转换出来的坐标:40.006500, 116.328023

由以上结果可以看出该算法的精度比较高,误差在10米之内。

如果大家觉得对自己有帮助的话,还希望能帮顶一下,谢谢:)

转载请注明出处,谢谢!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值