vue项目记录-高德地图2.0-坐标系问题

1.常见地图

高德地图、百度地图、腾讯地图、天地图、谷歌地图、arcgis地图、mapbox······

我们可以使用一个地图开发或者叠加图层,但是无论如何,你肯定会面对坐标系问题

2.常见坐标系

1、WGS-84坐标系:地心坐标系,GPS原始坐标体系

在中国,任何一个地图产品都不允许使用GPS坐标。

2、GCJ-02 坐标系:国测局坐标,火星坐标系

1)国测局02年发布的坐标体系,它是一种对经纬度数据的加密算法,即加入随机的偏差。

2)互联网地图在国内必须至少使用GCJ-02进行首次加密,不允许直接使用WGS-84坐标下的地理数据,同时任何坐标系均不可转换为WGS-84坐标。

3)是国内最广泛使用的坐标体系,高德、腾讯、Google中国地图都使用它。

3、CGCS2000坐标系:国家大地坐标系

该坐标系是通过中国GPS 连续运行基准站、 空间大地控制网以及天文大地网与空间地网联合平差建立的地心大地坐标系统。

4、BD-09坐标系

百度中国地图所采用的坐标系,由GCJ-02进行进一步的偏移算法得到。

3.地图对应坐标系

1、百度地图

1)境内(包括港澳台):BD09

a、在GCJ-02坐标系基础上再次加密

b、支持WGS-84、GCJ-02转换成BD09,反向不支持,并且批量转换一次有条数限制

2)境外:WGS-84

2、高德地图:

1)境内:GCJ-02

a、WGS-84——>GCJ-02(高德有接口提供,反过来没有)

2)境外:暂不支持

3)AMap 就是高德地图,是高德地图在纳斯达克上市用的名字,主要面向互联网企业或个人提供免费API服务

4)MapABC 是高德集团底下的图盟公司,主要面向大众型企业或政府机关,并提供付费的有偿服务

5)Amap和MapABC,数据和服务都是共享的,所以Mapabc用Amap的API是正常的

3、google地图

1)境内:GCJ-02

a、数据来源于高德,两者互通

2)境外:WGS-84

4、天地图

全球统一:CGCS2000

国外地图放大到一定层级后会显示没有影像

5、腾讯地图:soso地图

境内:GCJ02

4.坐标系转换方法

写一个坐标转换的工具类,需要使用的时候导入,代码在网上可以找到很多,这里贴一个作为例子(不完整)

const xPI = 3.14159265358979324 * 3000.0 / 180.0
const PI = 3.1415926535897932384626
const a = 6378245.0
const ee = 0.00669342162296594323

/**
 * 百度坐标系 (BD-09) 与 火星坐标系 (GCJ-02)的转换
 * 即 百度 转 谷歌、高德
 * @param bdlng
 * @param bdLat
 * @returns {*[]}
 */
function bd09togcj02 (bdlng, bdLat) {
  const x = bdlng - 0.0065
  const y = bdLat - 0.006
  const z = Math.sqrt(x * x + y * y) - 0.00002 * Math.sin(y * xPI)
  const theta = Math.atan2(y, x) - 0.000003 * Math.cos(x * xPI)
  const ggLng = z * Math.cos(theta)
  const ggLat = z * Math.sin(theta)
  return [ggLng, ggLat]
}

/**
* 火星坐标系 (GCJ-02) 与百度坐标系 (BD-09) 的转换
* 即谷歌、高德 转 百度
* @param lng
* @param lat
* @returns {*[]}
*/
function gcj02tobd09 (lng, lat) {
  const z = Math.sqrt(lng * lng + lat * lat) + 0.00002 * Math.sin(lat * xPI)
  const theta = Math.atan2(lat, lng) + 0.000003 * Math.cos(lng * xPI)
  const bdLng = z * Math.cos(theta) + 0.0065
  const bdLat = z * Math.sin(theta) + 0.006
  return [bdLng, bdLat]
}

/**
* WGS84转GCj02
* @param lng
* @param lat
* @returns {*[]}
*/
function wgs84togcj02 (lng, lat) {
  if (outOfChina(lng, lat)) {
    return [lng, lat]
  } else {
    let dlat = transformlat(lng - 105.0, lat - 35.0)
    let dlng = transformlng(lng - 105.0, lat - 35.0)
    const radlat = lat / 180.0 * PI
    let magic = Math.sin(radlat)
    magic = 1 - ee * magic * magic
    const sqrtmagic = Math.sqrt(magic)
    dlat = (dlat * 180.0) / ((a * (1 - ee)) / (magic * sqrtmagic) * PI)
    dlng = (dlng * 180.0) / (a / sqrtmagic * Math.cos(radlat) * PI)
    const mglat = lat + dlat
    const mglng = lng + dlng
    return [mglng, mglat]
  }
}

/**
* GCJ02 转换为 WGS84
* @param lng
* @param lat
* @returns {*[]}
*/
function gcj02towgs84 (lng, lat) {
  if (outOfChina(lng, lat)) {
    return [lng, lat]
  } else {
    let dlat = transformlat(lng - 105.0, lat - 35.0)
    let dlng = transformlng(lng - 105.0, lat - 35.0)
    const radlat = lat / 180.0 * PI
    let magic = Math.sin(radlat)
    magic = 1 - ee * magic * magic
    const sqrtmagic = Math.sqrt(magic)
    dlat = (dlat * 180.0) / ((a * (1 - ee)) / (magic * sqrtmagic) * PI)
    dlng = (dlng * 180.0) / (a / sqrtmagic * Math.cos(radlat) * PI)
    const mglat = lat + dlat
    const mglng = lng + dlng
    return [lng * 2 - mglng, lat * 2 - mglat]
  }
}

function transformlat (lng, lat) {
  let ret = -100.0 + 2.0 * lng + 3.0 * lat + 0.2 * lat * lat + 0.1 * lng * lat + 0.2 * Math.sqrt(Math.abs(lng))
  ret += (20.0 * Math.sin(6.0 * lng * PI) + 20.0 * Math.sin(2.0 * lng * PI)) * 2.0 / 3.0
  ret += (20.0 * Math.sin(lat * PI) + 40.0 * Math.sin(lat / 3.0 * PI)) * 2.0 / 3.0
  ret += (160.0 * Math.sin(lat / 12.0 * PI) + 320 * Math.sin(lat * PI / 30.0)) * 2.0 / 3.0
  return ret
}

function transformlng (lng, lat) {
  let ret = 300.0 + lng + 2.0 * lat + 0.1 * lng * lng + 0.1 * lng * lat + 0.1 * Math.sqrt(Math.abs(lng))
  ret += (20.0 * Math.sin(6.0 * lng * PI) + 20.0 * Math.sin(2.0 * lng * PI)) * 2.0 / 3.0
  ret += (20.0 * Math.sin(lng * PI) + 40.0 * Math.sin(lng / 3.0 * PI)) * 2.0 / 3.0
  ret += (150.0 * Math.sin(lng / 12.0 * PI) + 300.0 * Math.sin(lng / 30.0 * PI)) * 2.0 / 3.0
  return ret
}

/**
* 判断是否在国内,不在国内则不做偏移
* @param lng
* @param lat
* @returns {boolean}
*/
function outOfChina (lng, lat) {
  return (lng < 72.004 || lng > 137.8347) || ((lat < 0.8293 || lat > 55.8271) || false)
}

5.相关问题

国内地图一般是没有国外详细数据的,一般需要开通海外服务。谷歌地图使用需要使用魔法,需要代理服务器访问,目前项目上通过高德叠加mapbox的图层可以显示全球数据,但是加载慢。

6.相关链接

感谢:https://blog.csdn.net/m0_37738114/article/details/80452485

posted @ 2021-12-21 16:18  ATK无限大  阅读(820)  评论(0)    收藏  举报