|
| 1 | +--- |
| 2 | +layout: post |
| 3 | +category : JavaScript |
| 4 | +tagline: "" |
| 5 | +tags : [地图坐标转换,GCJ-02] |
| 6 | +--- |
| 7 | +{% include JB/setup %} |
| 8 | + |
| 9 | +由于最近在开发相关地图应用,所以不可必免的就会遇到`GPS`坐标(`WGS-84`)转换成国家测绘局标准要求的`GCJ-02`(所谓的火星坐标) |
| 10 | + |
| 11 | +关于`WGS-84`与`GCJ-02`可以参照这篇文章,<a href="http://bbs.amap.com/thread-18617-1-2.html" target="_blank">坐标转换、偏移</a>. |
| 12 | + |
| 13 | +下面的代码摘直网上,特收藏下 |
| 14 | + |
| 15 | +```js |
| 16 | + |
| 17 | +//World Geodetic System ==> Mars Geodetic System |
| 18 | +//translate from https://on4wp7.codeplex.com/SourceControl/changeset/view/21483#353936 |
| 19 | +var WGS84_to_GCJ02 = function() {} |
| 20 | + |
| 21 | +WGS84_to_GCJ02.prototype.a = 6378245.0; |
| 22 | +WGS84_to_GCJ02.prototype.ee = 0.00669342162296594323; |
| 23 | +WGS84_to_GCJ02.prototype.transform = function(wgLat, wgLon) { |
| 24 | + |
| 25 | + if (this.outOfChina(wgLat, wgLon)) { |
| 26 | + return [wgLat, wgLon]; |
| 27 | + } |
| 28 | + |
| 29 | + dLat = this.transformLat(wgLon - 105.0, wgLat - 35.0); |
| 30 | + dLon = this.transformLon(wgLon - 105.0, wgLat - 35.0); |
| 31 | + radLat = wgLat / 180.0 * Math.PI; |
| 32 | + magic = Math.sin(radLat); |
| 33 | + magic = 1 - this.ee * magic * magic; |
| 34 | + sqrtMagic = Math.sqrt(magic); |
| 35 | + dLat = (dLat * 180.0) / ((this.a * (1 - this.ee)) / (magic * sqrtMagic) * Math.PI); |
| 36 | + dLon = (dLon * 180.0) / (this.a / sqrtMagic * Math.cos(radLat) * Math.PI); |
| 37 | + mgLat = wgLat + dLat; |
| 38 | + mgLon = wgLon + dLon; |
| 39 | + |
| 40 | + return [mgLat, mgLon]; |
| 41 | + |
| 42 | +}; |
| 43 | + |
| 44 | +WGS84_to_GCJ02.prototype.outOfChina = function(lat, lon) { |
| 45 | + |
| 46 | + if (lon < 72.004 || lon > 137.8347) |
| 47 | + return true; |
| 48 | + if (lat < 0.8293 || lat > 55.8271) |
| 49 | + return true; |
| 50 | + |
| 51 | + return false; |
| 52 | + |
| 53 | +}; |
| 54 | + |
| 55 | +WGS84_to_GCJ02.prototype.transformLat = function(x, y) { |
| 56 | + |
| 57 | + var ret = -100.0 + 2.0 * x + 3.0 * y + 0.2 * y * y + 0.1 * x * y + 0.2 * Math.sqrt(Math.abs(x)); |
| 58 | + ret += (20.0 * Math.sin(6.0 * x * Math.PI) + 20.0 * Math.sin(2.0 * x * Math.PI)) * 2.0 / 3.0; |
| 59 | + ret += (20.0 * Math.sin(y * Math.PI) + 40.0 * Math.sin(y / 3.0 * Math.PI)) * 2.0 / 3.0; |
| 60 | + ret += (160.0 * Math.sin(y / 12.0 * Math.PI) + 320 * Math.sin(y * Math.PI / 30.0)) * 2.0 / 3.0; |
| 61 | + |
| 62 | + return ret; |
| 63 | + |
| 64 | +}; |
| 65 | + |
| 66 | +WGS84_to_GCJ02.prototype.transformLon = function(x, y) { |
| 67 | + |
| 68 | + var ret = 300.0 + x + 2.0 * y + 0.1 * x * x + 0.1 * x * y + 0.1 * Math.sqrt(Math.abs(x)); |
| 69 | + ret += (20.0 * Math.sin(6.0 * x * Math.PI) + 20.0 * Math.sin(2.0 * x * Math.PI)) * 2.0 / 3.0; |
| 70 | + ret += (20.0 * Math.sin(x * Math.PI) + 40.0 * Math.sin(x / 3.0 * Math.PI)) * 2.0 / 3.0; |
| 71 | + ret += (150.0 * Math.sin(x / 12.0 * Math.PI) + 300.0 * Math.sin(x / 30.0 * Math.PI)) * 2.0 / 3.0; |
| 72 | + |
| 73 | + return ret; |
| 74 | + |
| 75 | +}; |
| 76 | + |
| 77 | +``` |
| 78 | + |
| 79 | +使用例子如下: |
| 80 | + |
| 81 | +```js |
| 82 | + |
| 83 | +new WGS84_to_GCJ02().transform(31.283814, 121.502191) |
| 84 | +// -> [31.28181188043995, 121.50661885748906] (该坐标是上海同济大学) |
| 85 | + |
| 86 | +``` |
| 87 | + |
| 88 | +最后附上一个在线转换接口,<a href="http://www.zdoz.net/apiList.html" target="_blank">在线转换坐标接口</a> |
0 commit comments