Mapbar经纬坐标偏移的加/解密算法

具本人研究所知,Mapbar地图的成图算法并不难懂,并且它的地图成图算法没有进行加密(效果就是整个地图有一定的偏移,实际上它的成图是准确的),由此可想而知,它的坐标必定也未加密!

那么为什么我用真实的经纬坐标在Mapbar上标注的时候,会有明显的偏移呢?

在我们应用Mapbar开发一些应用的时候,我们所看到的或者是获取到的经纬度坐标其实都不是真正的地理坐标,而是经过Mapbar加密以后的坐标,所以对于外来的坐标Mapbar并不感冒。

在Mapbar的Api中,它会对传入的坐标进行一次解密(会获得真实的经纬度坐标),然后在Api的核心成图函数里就使用这个真实的坐标绘制用户可见的地图,而我们通过API获取的Mapbar坐标都是加密以后的坐标。

综上,如果你传给了Mapbar一个真实的坐标,因为它会对所有传入的坐标进行一次解密,因为我们传的本来就是真实的坐标,被它这么一解密反而就不真实了,于是这个不真实的坐标在后面成图中以及标注点上就有了偏移。

废话太多了,直接看代码吧!

经纬度加密算法如下:(PHP版)

/**
 * 将真实地理坐标加密为Mapbar经纬度坐标
 *
 * @param $x 经度值
 * @param $y 维度值
 * @returns array
 */
function coordOffsetEncrypt($x,$y){
    $x = floatval($x)*100000%36000000;
    $y = floatval($y)*100000%36000000;

    $_X = intval(((cos($y/100000))*($x/18000))+((sin($x/100000))*($y/9000))+$x);
    $_Y = intval(((sin($y/100000))*($x/18000))+((cos($x/100000))*($y/9000))+$y);

    return array($_X/100000.0,$_Y/100000.0);
}

经纬坐标加密算法(Javascript版)

/**
 * 将真实地理坐标加密为Mapbar经纬度坐标
 *
 * @param x 经度值
 * @param y 维度值
 * @returns [x,y]
 */
function coordOffsetEncrypt(x, y) {
    var x = parseFloat(x) * 100000 % 36000000;
    var y = parseFloat(y) * 100000 % 36000000;

    var _x = parseFloat(((Math.cos(y / 100000)) * (x / 18000)) + ((Math.sin(x / 100000)) * (y / 9000)) + x);
    var _y = parseFloat(((Math.sin(y / 100000)) * (x / 18000)) + ((Math.cos(x / 100000))*(y/9000))+y);

    return [_x / 100000.0, _y / 100000.0];
}

经纬度坐标解密算法(PHP版)

/**
 * 将Mapbar经纬坐标解密为真实地理坐标
 *
 * @param $x 经度值
 * @param $y 维度值
 * @returns array
 */
function croodOffsetDecrypt($x,$y){
    $x = floatval($x)*100000%36000000;
    $y = floatval($y)*100000%36000000;

    $x1 = intval(-(((cos($y/100000))*($x/18000))+((sin($x/100000))*($y/9000)))+$x);
    $y1 = intval(-(((sin($y/100000))*($x/18000))+((cos($x/100000))*($y/9000)))+$y);

    $x2 = intval(-(((cos($y1/100000))*($x1/18000))+((sin($x1/100000))*($y1/9000)))+$x+(($x>0)?1:-1));
    $y2 = intval(-(((sin($y1/100000))*($x1/18000))+((cos($x1/100000))*($y1/9000)))+$y+(($y>0)?1:-1));

    return array($x2/100000.0,$y2/100000.0);
}

经纬度坐标解密算法(Javascript版)

/**
 * 将Mapbar经纬坐标解密为真实地理坐标
 *
 * @param x 经度值
 * @param y 维度值
 * @returns [x,y]
 */
function croodOffsetDecrypt(x, y){
    var x = parseFloat(x) * 100000 % 36000000;
    var y = parseFloat(y) * 100000 % 36000000;

    var x1 = parseInt(-(((Math.cos(y / 100000)) * (x / 18000)) + ((Math.sin(x / 100000)) * (y / 9000))) + x);
    var y1 = parseInt(-(((Math.sin(y / 100000)) * (x / 18000)) + ((Math.cos(x / 100000)) * (y / 9000))) + y);

    var x2 = parseInt(-(((Math.cos(y1 / 100000)) * (x1 / 18000)) + ((Math.sin(x1 / 100000)) * (y1 / 9000))) + x + ((x > 0) ? 1 : -1));
    var y2 = parseInt(-(((Math.sin(y1 / 100000))  *(x1 / 18000)) + ((Math.cos(x1 / 100000)) * (y1 / 9000))) + y + ((y > 0) ? 1 : -1));

    return [x2 / 100000.0, y2 / 100000.0];
}

演示

作者:煎饼

我是本站站长

114条评论

  1. 我按照demo的地址连接测试一下,发现跟google地图定位仍然有偏差,不知是不是我的js解密有错误(网上的js解密方法)

      1. 我的意思是:将Mapbar经纬度坐标转换为真实地理经纬度坐标后,将真实的地理经纬度换成google的地图发现有偏差。google不是真实的地理经纬度坐标吗?

  2. 啊啊啊啊,我费了好打功夫才把百度坐标转地理坐标,最后才看到这里,学习了,谢谢楼主!

  3. 老兄,我刚还兴奋呢,试验了一下,好像不对,难道百度和MAPBAR的偏移不一样吗?

  4. (惊恐) 不准确的,gps采集坐标30.2820 120.113161,算法算到的坐标 120.10808 ,30.28553 杭州文二路上的跑到文一路上去了

  5. 经过辛苦工作,终于开发出精确到0.001的算法, 具体效果可以到这里看看: http://www.lbsbase.com CHINA Mozilla Firefox Windows 说道:

    经过辛苦工作,终于开发出精确到0.001的算法,
    具体效果可以到这里看看:
    http://www.lbsbase.com

  6. 我试了一下,这个解密算法,发现不能用啊,现在mapbar返回的是像 ICGGEDWVDRHFV的加密字符串,找了网上的一些解密算法,似乎结果都差一点,不知道您是怎么解决的

      1. 您能告诉我一下,怎么获取到mapbar的经纬度吗?我查到的破poi 的地址似乎都是加密的字符串,如何解密?或者能通过邮件告诉我一下。谢谢!

      1. 你好,我发现加密解密可以用,且正确,但是mapbar坐标转实际坐标存在些问题。有无解决办法?或者提点下思路,我试着自己解决。

发表评论

您的电子邮箱地址不会被公开。 必填项已用*标注