JS经纬度坐标转换 挺准确的
1 data() { 2 return { 3 PI: 3.14159265358979324, 4 x_pi: (3.14159265358979324 * 3000.0) / 180.0 5 } 6 }, 7 methods: { 8 delta(lat, lon) { 9 // Krasovsky 1940 10 // 11 // a = 6378245.0, 1/f = 298.3 12 // b = a * (1 - f) 13 // ee = (a^2 - b^2) / a^2 14 const a = 6378245.0 // a: 卫星椭球坐标投影到平面地图坐标系的投影因子。 15 const ee = 0.00669342162296594323 // ee: 椭球的偏心率。 16 let dLat = this.transformLat(lon - 105.0, lat - 35.0) 17 let dLon = this.transformLon(lon - 105.0, lat - 35.0) 18 const radLat = (lat / 180.0) * this.PI 19 let magic = Math.sin(radLat) 20 magic = 1 - ee * magic * magic 21 const sqrtMagic = Math.sqrt(magic) 22 dLat = (dLat * 180.0) / (((a * (1 - ee)) / (magic * sqrtMagic)) * this.PI) 23 dLon = (dLon * 180.0) / ((a / sqrtMagic) * Math.cos(radLat) * this.PI) 24 return { lat: dLat, lon: dLon } 25 }, 26 // WGS-84 to GCJ-02 27 gcj_encrypt(wgsLat, wgsLon) { 28 if (this.outOfChina(wgsLat, wgsLon)) { 29 return { lat: wgsLat, lon: wgsLon } 30 } 31 const d = this.delta(wgsLat, wgsLon) 32 return { lat: wgsLat + d.lat, lon: wgsLon + d.lon } 33 }, 34 // GCJ-02 to WGS-84 35 gcj_decrypt(gcjLat, gcjLon) { 36 if (this.outOfChina(gcjLat, gcjLon)) { 37 return { lat: gcjLat, lon: gcjLon } 38 } 39 const d = this.delta(gcjLat, gcjLon) 40 return { lat: gcjLat - d.lat, lon: gcjLon - d.lon } 41 }, 42 // GCJ-02 to WGS-84 exactly 43 gcj_decrypt_exact(gcjLat, gcjLon) { 44 const initDelta = 0.01 45 const threshold = 0.000000001 46 let dLat = initDelta 47 let dLon = initDelta 48 let mLat = gcjLat - dLat 49 let mLon = gcjLon - dLon 50 let pLat = gcjLat + dLat 51 let pLon = gcjLon + dLon 52 let wgsLat 53 let wgsLon 54 let i = 0 55 while (1) { 56 wgsLat = (mLat + pLat) / 2 57 wgsLon = (mLon + pLon) / 2 58 const tmp = this.gcj_encrypt(wgsLat, wgsLon) 59 dLat = tmp.lat - gcjLat 60 dLon = tmp.lon - gcjLon 61 if (Math.abs(dLat) < threshold && Math.abs(dLon) < threshold) { 62 break 63 } 64 65 if (dLat > 0) { 66 pLat = wgsLat 67 } else { 68 mLat = wgsLat 69 } 70 if (dLon > 0) { 71 pLon = wgsLon 72 } else { 73 mLon = wgsLon 74 } 75 if (++i > 10000) { 76 break 77 } 78 } 79 // console.log(i) 80 return { lat: wgsLat, lon: wgsLon } 81 }, 82 // GCJ-02 to BD-09 83 bd_encrypt(gcjLat, gcjLon) { 84 const x = gcjLon 85 const y = gcjLat 86 const z = Math.sqrt(x * x + y * y) + 0.00002 * Math.sin(y * this.x_pi) 87 const theta = Math.atan2(y, x) + 0.000003 * Math.cos(x * this.x_pi) 88 const bdLon = z * Math.cos(theta) + 0.0065 89 const bdLat = z * Math.sin(theta) + 0.006 90 return { lat: bdLat, lon: bdLon } 91 }, 92 // BD-09 to GCJ-02 93 bd_decrypt(bdLat, bdLon) { 94 const x = bdLon - 0.0065 95 const y = bdLat - 0.006 96 const z = Math.sqrt(x * x + y * y) - 0.00002 * Math.sin(y * this.x_pi) 97 const theta = Math.atan2(y, x) - 0.000003 * Math.cos(x * this.x_pi) 98 const gcjLon = z * Math.cos(theta) 99 const gcjLat = z * Math.sin(theta) 100 return { lat: gcjLat, lon: gcjLon } 101 }, 102 // WGS-84 to Web mercator 103 // mercatorLat -> y mercatorLon -> x 104 mercator_encrypt: function(wgsLat, wgsLon) { 105 const x = (wgsLon * 20037508.34) / 180.0 106 let y = 107 Math.log(Math.tan(((90.0 + wgsLat) * this.PI) / 360.0)) / 108 (this.PI / 180.0) 109 y = (y * 20037508.34) / 180.0 110 return { lat: y, lon: x } 111 /* 112 if ((Math.abs(wgsLon) > 180 || Math.abs(wgsLat) > 90)) 113 return null 114 var x = 6378137.0 * wgsLon * 0.017453292519943295 115 var a = wgsLat * 0.017453292519943295 116 var y = 3189068.5 * Math.log((1.0 + Math.sin(a)) / (1.0 - Math.sin(a))) 117 return {'lat' : y, 'lon' : x} 118 //*/ 119 }, 120 // Web mercator to WGS-84 121 // mercatorLat -> y mercatorLon -> x 122 mercator_decrypt: function(mercatorLat, mercatorLon) { 123 const x = (mercatorLon / 20037508.34) * 180.0 124 let y = (mercatorLat / 20037508.34) * 180.0 125 y = 126 (180 / this.PI) * 127 (2 * Math.atan(Math.exp((y * this.PI) / 180.0)) - this.PI / 2) 128 return { lat: y, lon: x } 129 /* 130 if (Math.abs(mercatorLon) < 180 && Math.abs(mercatorLat) < 90) 131 return null 132 if ((Math.abs(mercatorLon) > 20037508.3427892) || (Math.abs(mercatorLat) > 20037508.3427892)) 133 return null 134 var a = mercatorLon / 6378137.0 * 57.295779513082323 135 var x = a - (Math.floor(((a + 180.0) / 360.0)) * 360.0) 136 var y = (1.5707963267948966 - (2.0 * Math.atan(Math.exp((-1.0 * mercatorLat) / 6378137.0)))) * 57.295779513082323 137 return {'lat' : y, 'lon' : x} 138 //*/ 139 }, 140 // two point's distance 141 distance(latA, lonA, latB, lonB) { 142 const earthR = 6371000.0 143 const x = 144 Math.cos((latA * this.PI) / 180.0) * 145 Math.cos((latB * this.PI) / 180.0) * 146 Math.cos(((lonA - lonB) * this.PI) / 180) 147 const y = 148 Math.sin((latA * this.PI) / 180.0) * Math.sin((latB * this.PI) / 180.0) 149 let s = x + y 150 if (s > 1) { 151 s = 1 152 } 153 if (s < -1) { 154 s = -1 155 } 156 const alpha = Math.acos(s) 157 const distance = alpha * earthR 158 return distance 159 }, 160 outOfChina(lat, lon) { 161 if (lon < 72.004 || lon > 137.8347) { 162 return true 163 } 164 if (lat < 0.8293 || lat > 55.8271) { 165 return true 166 } 167 return false 168 }, 169 transformLat(x, y) { 170 let ret = 171 -100.0 + 172 2.0 * x + 173 3.0 * y + 174 0.2 * y * y + 175 0.1 * x * y + 176 0.2 * Math.sqrt(Math.abs(x)) 177 ret += 178 ((20.0 * Math.sin(6.0 * x * this.PI) + 179 20.0 * Math.sin(2.0 * x * this.PI)) * 180 2.0) / 181 3.0 182 ret += 183 ((20.0 * Math.sin(y * this.PI) + 40.0 * Math.sin((y / 3.0) * this.PI)) * 184 2.0) / 185 3.0 186 ret += 187 ((160.0 * Math.sin((y / 12.0) * this.PI) + 188 320 * Math.sin((y * this.PI) / 30.0)) * 189 2.0) / 190 3.0 191 return ret 192 }, 193 transformLon(x, y) { 194 let ret = 195 300.0 + 196 x + 197 2.0 * y + 198 0.1 * x * x + 199 0.1 * x * y + 200 0.1 * Math.sqrt(Math.abs(x)) 201 ret += 202 ((20.0 * Math.sin(6.0 * x * this.PI) + 203 20.0 * Math.sin(2.0 * x * this.PI)) * 204 2.0) / 205 3.0 206 ret += 207 ((20.0 * Math.sin(x * this.PI) + 40.0 * Math.sin((x / 3.0) * this.PI)) * 208 2.0) / 209 3.0 210 ret += 211 ((150.0 * Math.sin((x / 12.0) * this.PI) + 212 300.0 * Math.sin((x / 30.0) * this.PI)) * 213 2.0) / 214 3.0 215 return ret 216 } 217 } 218 }