澳门新萄京境内各地图API坐标体系较和转移(做LBS的对象请求转)「转」电子地图坐标体系钻研整理。

付出LBS的心上人看

「博客搬家」 原地址:
CSDN
原登时: 2016-04-15

本文由文末的参照链接整理、整合、修改要成

一样、各个坐标系的概况

1. 电子地图坐标体系简介

  • WGS-84 坐标系:即地球坐标系,国际经纬度坐标标准
  • GCJ-02 坐标系:即火星坐标系,WGS84
    坐标系经加密后底坐标系,国测局制定。
  • BD-09 坐标系:即百过以标系,GCJ02 坐标系经加密后的坐标系。

GCJ-02 坐标体系,就是当正规的 WGS-84 坐标体系及展开了人工的摇,比如
Google 地图、腾讯 SOSO 地图等便是直采用了国家 GCJ-02
坐标体系,我们出一个休成文的说法,前者被地球坐标,后者于火星坐标,并且,火星坐标是无能为力转换成球坐标的「网上虽发早晚之法门,但差不多还是依据偏移数据库,精度比高之数据库需要请,当然就都是同一种植破解手段」。

负有的电子地图、导航设备,都亟需投入国家保密插件。第一步,地图公司测绘地图,测绘完成后,送至国家测绘局,将真坐标的电子地图,加密成“火星坐标”,这样的地图才是足以出版和公布之,然后才足以叫
GPS 公司处理。第二步,所有的 GPS
公司,只要用汽车导航的,需要以导航电子地图的,都得在软件受到在国家保密算法,将
COM 口读出来的真实的坐标信号,加密转换成为国家要求的秘的坐标。这样,GPS
导航仪和导航电子地图就是得完全匹配,GPS 也尽管好健康办事了。

API 坐标系
百度地图 API 百度坐标
腾讯搜搜地图 API 火星坐标
搜狐搜狗地图 API 搜狗坐标
阿里云地图 API 火星坐标
图吧 MapBar 地图 API 图吧坐标
高德 MapABC 地图 API 火星坐标
灵图 51ditu 地图 API 火星坐标
  • 注1:百度地图使用百度坐标,支持自地坐标和火星坐标导入成百度坐标,但无能为力导出。并且批量坐标转换一不良只能换20独(待验证)。
  • 注2:搜狗地图支持直接展示地球坐标,支持地球坐标、火星坐标、百度坐标导入成搜狗坐标,同样,搜狗坐标也无力回天导出。

说了坐标体系,我们当能解这里的题材,通过以下问题,来说说自本着这个之研讨。

肯定地球是一个不规则椭圆体,GIS中的坐标系定义由基准面和地图投影两组参数确定,而基准面的概念则是因为特定椭球体及其相应的变换参数确定。
基准面是采取特定椭球体对特定地段地球表面的压,因此每个国家或所在皆有独家的基准面。基准面是在椭球体基础及成立之,椭球体可以本着承诺多独基准面,而基准面只能对应一个椭球体。意思就是是凭谷歌地图、搜搜地图还是高德地图、百度地图区别就是对不同的五洲地理坐标系正式打造的中纬度,不存在以不准的问题,大家还是随的仅是参照物或者说是标准不平等。谷歌地图采用的是WGS84地理坐标系(中国范围除去),谷歌中国地形图及搜搜中国地图采用的凡GCJ02地理坐标系,百度采用的凡BD09坐标系,而装备一般含GPS芯片或北斗芯片取得的中纬度为WGS84地理坐标系,为什么不合并用WGS84地理坐标系这就是是国家地理测绘总局对出版地图的求,出版地图必须符合GCJ02坐标系标准了,也就是是国确定不能够直接使用WGS84地理坐标系。所以一定大家觉得不规范很多而且给出版地图为火星地图其实只是是坐标系不一致而已。这就算是干吗设备采集的经纬度在地图上亮的时段经常闹好可怜的不是,远远大于民用GPS
10米偏移量的技巧标准。

2、各个坐标系的彼此转换

以上参考自:haotsp.com

2.1 火星坐标系「GCJ-02」与百度坐标系「BD-09」的转移算法

其中 bd_encrypt 用 GCJ-02 坐标转换成为 BD-09 坐标, bd_decrypt 反之。

void bd_encrypt(double gg_lat, double gg_lon, double &bd_lat, double &bd_lon)  
{  
    double x = gg_lon, y = gg_lat;  
    double z = sqrt(x * x + y * y) + 0.00002 * sin(y * x_pi);  
    double theta = atan2(y, x) + 0.000003 * cos(x * x_pi);  
    bd_lon = z * cos(theta) + 0.0065;  
    bd_lat = z * sin(theta) + 0.006;  
}  
void bd_decrypt(double bd_lat, double bd_lon, double &gg_lat, double &gg_lon)  
{  
    double x = bd_lon - 0.0065, y = bd_lat - 0.006;  
    double z = sqrt(x * x + y * y) - 0.00002 * sin(y * x_pi);  
    double theta = atan2(y, x) - 0.000003 * cos(x * x_pi);  
    gg_lon = z * cos(theta);  
    gg_lat = z * sin(theta);  
}  

总结:

2.2 地球坐标系「WGS-84」到火星坐标系「GCJ-02」的变算法

WGS-84 到 GCJ-02 的转换「即 GPS 加偏」算法

using System;   
namespace Navi  
{  
    class EvilTransform  
    {  
        const double pi = 3.14159265358979324;  
        //   
        // Krasovsky 1940   
        //   
        // a = 6378245.0, 1/f = 298.3   
        // b = a * (1 - f)   
        // ee = (a^2 - b^2) / a^2;   
        const double a = 6378245.0;  
        const double ee = 0.00669342162296594323;  
        //   
        // World Geodetic System ==> Mars Geodetic System   
        public static void transform(double wgLat, double wgLon, out double mgLat, out double mgLon)  
        {  
            if (outOfChina(wgLat, wgLon))  
            {  
                mgLat = wgLat;  
                mgLon = wgLon;  
                return;  
            }  
            double dLat = transformLat(wgLon - 105.0, wgLat - 35.0);  
            double dLon = transformLon(wgLon - 105.0, wgLat - 35.0);  
            double radLat = wgLat / 180.0 * pi;  
            double magic = Math.Sin(radLat);  
            magic = 1 - ee * magic * magic;  
            double sqrtMagic = Math.Sqrt(magic);  
            dLat = (dLat * 180.0) / ((a * (1 - ee)) / (magic * sqrtMagic) * pi);  
            dLon = (dLon * 180.0) / (a / sqrtMagic * Math.Cos(radLat) * pi);  
            mgLat = wgLat + dLat;  
            mgLon = wgLon + dLon;  
        }  
        static bool outOfChina(double lat, double lon)  
        {  
            if (lon < 72.004 || lon > 137.8347)  
                return true;  
            if (lat < 0.8293 || lat > 55.8271)  
                return true;  
            return false;  
        }  
        static double transformLat(double x, double y)  
        {  
            double ret = -100.0 + 2.0 * x + 3.0 * y + 0.2 * y * y + 0.1 * x * y + 0.2 * Math.Sqrt(Math.Abs(x));  
            ret += (20.0 * Math.Sin(6.0 * x * pi) + 20.0 * Math.Sin(2.0 * x * pi)) * 2.0 / 3.0;  
            ret += (20.0 * Math.Sin(y * pi) + 40.0 * Math.Sin(y / 3.0 * pi)) * 2.0 / 3.0;  
            ret += (160.0 * Math.Sin(y / 12.0 * pi) + 320 * Math.Sin(y * pi / 30.0)) * 2.0 / 3.0;  
            return ret;  
        }  
        static double transformLon(double x, double y)  
        {  
            double ret = 300.0 + x + 2.0 * y + 0.1 * x * x + 0.1 * x * y + 0.1 * Math.Sqrt(Math.Abs(x));  
            ret += (20.0 * Math.Sin(6.0 * x * pi) + 20.0 * Math.Sin(2.0 * x * pi)) * 2.0 / 3.0;  
            ret += (20.0 * Math.Sin(x * pi) + 40.0 * Math.Sin(x / 3.0 * pi)) * 2.0 / 3.0;  
            ret += (150.0 * Math.Sin(x / 12.0 * pi) + 300.0 * Math.Sin(x / 30.0 * pi)) * 2.0 / 3.0;  
            return ret;  
        }  
    }  
}  

以上参考自:http://www.xue5.com/Mobile/iOS/679842.html

WGS84以标系:即地球坐标系,国际直达通用的坐标系。

2.3 百度在线转换API

http://api.map.baidu.com/ag/coord/convert?from=0&to=4&x=longitude&y=latitude
from: 来源坐标系「0 表示 WGS-84 坐标;2 表示GCJ-02 坐标」
to: 转换后的坐标「4 表示 BD-09 坐标,即百度地图使用的实践」
x: 经度
y: 纬度

告后会回一错 Json

{  
    "error":0,  
    "x":"MTIxLjUwMDIyODIxNDk2",  
    "y":"MzEuMjM1ODUwMjYwMTE3"  
}  
error:是结果是否出错标志位,0 表示成功
x: 坐标系 2 时为经度,4 时为纬度(Base64编码)
y: 坐标系 4 时为经度,2 时为纬度(Base64编码)

啊动静,经纬度居然还加密?那接下吗只好见招拆招了

import java.io.BufferedReader;  
import java.io.IOException;  
import java.io.InputStream;  
import java.io.InputStreamReader;  
import java.io.OutputStreamWriter;  
import java.net.URL;  
import java.net.URLConnection;  
import com.sun.org.apache.xerces.internal.impl.dv.util.Base64;  
public class BaiduAPIConverter extends Thread {  
  public static void testPost(String x, String y) throws IOException {  
    try {  
      URL url = new URL("http://api.map.baidu.com/ag/coord/convert?from=2&to=4&x="+ x + "&y=" + y);  
      URLConnection connection = url.openConnection();  
      connection.setDoOutput(true);  
      OutputStreamWriter out = new OutputStreamWriter(connection.getOutputStream(), "utf-8");  
      // remember to clean up   
      out.flush();  
      out.close();  
      // 一旦发送成功,用以下方法就可以得到服务器的回应:   
      String sCurrentLine, sTotalString;  
      sCurrentLine = sTotalString = "";  
      InputStream l_urlStream;  
      l_urlStream = connection.getInputStream();  
      BufferedReader l_reader = new BufferedReader(new InputStreamReader(l_urlStream));  
      while ((sCurrentLine = l_reader.readLine()) != null) {  
        if (!sCurrentLine.equals(""))  
          sTotalString += sCurrentLine;  
      }  
      sTotalString = sTotalString.substring(1, sTotalString.length() - 1);  
      String[] results = sTotalString.split("\\,");  
      if (results.length == 3) {  
        if (results[0].split("\\:")[1].equals("0")) {  
          String mapX = results[1].split("\\:")[1];  
          String mapY = results[2].split("\\:")[1];  
          mapX = mapX.substring(1, mapX.length() - 1);  
          mapY = mapY.substring(1, mapY.length() - 1);  
          mapX = new String(Base64.decode(mapX));  
          mapY = new String(Base64.decode(mapY));  
          System.out.println("\t" + mapX + "\t" + mapY);  
        }  
      }  
     sleep(10000);  
    } catch (InterruptedException e) {  
      // TODO Auto-generated catch block   
      e.printStackTrace();  
    }  
  }  
  /** 
   * @param args 
   * @throws IOException 
   */  
  public static void main(String[] args) throws IOException {  
    testPost("120.151379", "30.184678");  
    System.out.println("ok");  
  }  
}  

至此为大抵好了,主要的代码都写出来了,其他的而便好写吧。
如上参考自:http://scalpel.me/archives/136

GCJ02坐标系:即火星坐标系,WGS84因标系经加密后的坐标系。

2.4 百度内置转换方法,可以无囿于为百度定位 SDK

于百度地图中获 WGS-84 坐标,调用如下方法:

BMapManager.getLocationManager().setLocationCoordinateType(MKLocationManager.MK_COORDINATE_WGS84);

这样于百度 API 中获得的坐标就是 WGS-84
了,可是这种坐标如果显示到百度地图及就是见面偏移,也就是说取出一个坐标,原封不动的来得上去不怕偏偏移了,所以为了显得为是正常就需以绘制到百度地图上事先转换成
BD-09 。
转移成为 BD-09,调用方法:

GeoPoint wgs84;
GeoPoint bd09= CoordinateConvert.bundleDecode(CoordinateConvert.fromWgs84ToBaidu(wgs84));

此处实在不懂得怎么要规划成 CoordinateConvert.fromWgs84ToBaidu(wgs84)
返回了一个 Bundle,所以还索要 CoordinateConvert.bundleDecode() 再转成
GeoPoint 。

BD09为标系:即百度因为标系,GCJ02坐标系经加密后底坐标系。

3. 参考文章

  1. 境内各地图API坐标体系较和易
  2. 至于百度地图坐标转换接口的研究
  3. 构建协调之百度地图坐标纠偏数据库
  4. GPS纠偏算法,适用于google,高德体系的地形图

搜狗坐标系、图吧坐标系等,估计也是在GCJ02基础及加密而变成的。


其次、各个地图API采用的坐标系

API坐标系

百度地图API百度坐标

腾讯搜搜地图API火星坐标

搜狐搜狗地图API搜狗坐标*

阿里云地图API火星坐标

贪图吧MapBar地图API图吧坐标

高德MapABC地图API火星坐标

灵图51ditu地图API火星坐标

注1:百度地图使用百度坐标,支持从地坐标和火星坐标导入成百度坐标,但无能为力导出。并且批量坐标转换一软只能换20只(待验证)。

注2:搜狗地图支持直接显示地球坐标,支持地球坐标、火星坐标、百度坐标导入成搜狗坐标,同样,搜狗坐标也无能为力导出。

村办认为:采用自坐标体系,而休使用国内通用的火星坐标体系,实在是自寻短处。当然,百度是坐做的足大、足够好,所以特别不可理喻,也为下一统天下而无深受别人瓜分之而做准备吧。搜狗虽然用自家坐标体系,但会拿球坐标直接导入,此举为属于唯一。而贪图吧地图不亮学什么加密方法,以前之所以地球坐标用底精粹的,现在因此图吧自己的坐标,难道是盖受百度做过因此呢来了这么一招?或者沿用百度?不得而知。

本文的目的在:做地图开发的下,不愿意吃同小地图API迁就,所以下火星坐标是对的选择,希望本文能够针对选择以谁家API的开发者提供一些助吧。就自我个人而言,我不要会使非火星坐标体系的地图API,虽然百度地图API很好死强大确实怪吸引我。

上述参考自:http://rovertang.com/labs/map-compare/


老三、各个坐标系的互相转换

1.火星坐标系 (GCJ-02) 与百度坐标系 (BD-09) 的转换算法,其中bd_encrypt将
GCJ-02 坐标转换成 BD-09 坐标,bd_decrypt反之。


2.球坐标系 (WGS-84) 到火星坐标系 (GCJ-02) 的变换算法

WGS-84 到 GCJ-02 的转换(即 GPS 加偏)算法

上述参考自:http://www.xue5.com/Mobile/iOS/679842.html


3.百度在线转换API

求后会回到一差Json

哟情形,经纬度居然尚加密?那接下去为不得不见招拆招了

顶这里吧大抵好了,主要的代码都勾出来了,其他的乃便自己写吧。

如上参考自:http://scalpel.me/archives/136/


季、重点啊,原来百度有坐转换方法,这生得以无局限为百度定位SDK了

于百度地图中拿走WGS-84坐标,调用如下方法:

BMapManager.getLocationManager().setLocationCoordinateType(MKLocationManager.MK_COORDINATE_WGS84);

诸如此类由百度api中获取的坐标就是WGS-84了,可是这种坐标如果显示到百度地图上就是会见偏移,也就是说取出一个坐标,原封不动的展示上去就偏偏移了,所以为了展示也是健康就需在绘制到百度地图及前面转换成BD-09。

换成BD-09,调用方法:

GeoPoint wgs84;

GeoPoint bd09 =
CoordinateConvert.bundleDecode(CoordinateConvert.fromWgs84ToBaidu(wgs84));

此实在不亮堂为什么要规划成CoordinateConvert.fromWgs84ToBaidu(wgs84)返回了一个Bundle,所以还亟需CoordinateConvert.bundleDecode()再转成为GeoPoint。


IOS端进行澳门新萄京的变


推介阅读:

Facebook
Paper使用的老三方库(强烈推荐)

iOS/Mac
开发博客列表(不断更新中)

作一个iOS开发使看的网站,一定对您行之,相信自己!

加强iOS开发效率的艺术和工具

IM系统架构设计之皮毛见

nil、Nil、NULL和NSNull的理解

相关文章

发表评论

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