wgs84,bd09,gcj02坐标切换

坐标转换算法

Posted by Ayi on December 25, 2018

利用百度api,高德api做前端页面的时候可能会涉及到一些坐标转换的问题,因此借鉴网上一些代码后,整理了一份js版的坐标转换代码

JS版

const xpi = 3.14159265358979324 * 3000.0 / 180.0 // π
const pi = 3.1415926535897932384626 // 长半轴
const a = 6378245.0 // 扁率
const ee = 0.00669342162296594323

const coordtransform = {
  bd09togcj02 (bdlng, bdlat) {
    let x = bdlng - 0.0065
    let y = bdlat - 0.006
    let z = Math.sqrt(x * x + y * y) - 0.00002 * Math.sin(y * xpi)
    let theta = Math.atan2(y, x) - 0.000003 * Math.cos(x * xpi)
    let gglng = z * Math.cos(theta)
    let gglat = z * Math.sin(theta)
    let arr = []
    arr[0] = gglng
    arr[1] = gglat
    return arr
  },
  gcj02towgs84 (lng, lat) {
    if (this.outofchina(lng, lat)) {
      let arr = []
      arr[0] = lng
      arr[1] = lat
      return arr
    }
    let dlat = this.transformlat(lng - 105.0, lat - 35.0)
    let dlng = this.transformlng(lng - 105.0, lat - 35.0)
    let radlat = lat / 180.0 * pi
    let magic = Math.sin(radlat)
    magic = 1 - ee * magic * magic
    let sqrtmagic = Math.sqrt(magic)
    dlat = (dlat * 180.0) / ((a * (1 - ee)) / (magic * sqrtmagic) * pi)
    dlng = (dlng * 180.0) / (a / sqrtmagic * Math.cos(radlat) * pi)
    let mglat = lat + dlat
    let mglng = lng + dlng
    let arr = []
    let newlng = lng * 2 - mglng
    let newlat = lat * 2 - mglat
    arr[0] = newlng
    arr[1] = newlat
    return arr
  },
  // 纬度转换
  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
  },
  // 经度转换
  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
  },
  // 判断是否在国内,不在国内不做偏移
  outofchina (lng, lat) {
    if (lng < 72.004 || lat > 137.8347) {
      return true
    } else if (lat < 0.8293 || lat > 55.8271) {
      return true
    }
    return false
  },
  // 百度坐标转WGS坐标
  bd09towgs84 (lng, lat) {
    let gcj = []
    gcj = this.bd09togcj02(lng, lat)
    let wgs84 = []
    wgs84 = this.gcj02towgs84(gcj[0], gcj[1])
    return wgs84
  },
  // WGS坐标转百度坐标
  wgs84tobd09 (lng, lat) {
    let gcj = []
    gcj = this.wgs84togcj02(lng, lat)
    let bd09 = []
    bd09 = this.gcj02tobd09(gcj[0], gcj[1])
    return bd09
  },
  // gcj02转bd09
  gcj02tobd09 (lng, lat) {
    let z = Math.sqrt(lng * lng + lat * lat) + 0.00002 * Math.sin(lat * xpi)
    let theta = Math.atan2(lat, lng) + 0.000003 * Math.cos(lng * xpi)
    let bdlng = z * Math.cos(theta) + 0.0065
    let bdlat = z * Math.sin(theta) + 0.006
    let bd = []
    bd[0] = bdlng
    bd[1] = bdlat
    return bd
  },
  // wgs84转bd09
  wgs84togcj02 (lng, lat) {
    if (this.outofchina(lng, lat)) {
      let arr = []
      arr[0] = lng
      arr[1] = lat
      return arr
    }
    let dlat = this.transformlat(lng - 105.0, lat - 35.0)
    let dlng = this.transformlng(lng - 105.0, lat - 35.0)
    let radlat = lat / 180.0 * pi
    let magic = Math.sin(radlat)
    magic = 1 - ee * magic * magic
    let sqrtmagic = Math.sqrt(magic)
    dlat = (dlat * 180.0) / ((a * (1 - ee)) / (magic * sqrtmagic) * pi)
    dlng = (dlng * 180.0) / (a / sqrtmagic * Math.cos(radlat) * pi)
    let mglat = lat + dlat
    let mglng = lng + dlng
    let arr = []
    arr[0] = mglng
    arr[1] = mglat
    return arr
  }
}

export default coordtransform

Java版

参考jp1017的github