Geographic coordinate conversion

Posted by pieychpi on Mon, 30 Dec 2019 15:30:14 +0100

I am a program ape, the work is mainly about the development of GIS system. In GIS, do you know how many coordinate systems a map has?

I don't know! Then I'll introduce you.

WGS84 coordinate system

GPS, WGS-84, original coordinate system. Generally, the coordinates recorded by the international standard GPS recorder are all GPS coordinates. Unfortunately, GPS coordinates are not allowed for any map product in China, which is said to be confidential.

GCJ02 coordinate system

Coordinate system issued by the State Administration of survey and survey in 2002. Also known as "Mars coordinates". In China, the coordinate system of GCJ-02 must be used at least. For example, Tencent and Gaode are using this coordinate system. GCJ-02 is also the most widely used coordinate system in China.

BD09 coordinate system

Baidu coordinate system, GCJ02 coordinate system encrypted coordinate system

So what happens when these coordinates are converted to each other? Then I recommend a conversion code written in JavaScript:

/** * Map coordinate converter *  */var GPS2Google2Baidu = {    PI: 3.14159265358979324,    x_pi: 3.14159265358979324 * 3000.0 / 180.0,    delta: function (lat, lng) {        // Krasovsky 1940        //        // a = 6378245.0, 1/f = 298.3        // b = a * (1 - f)        // ee = (a^2 - b^2) / a^2;        var a = 6378245.0; //  a: The projection factor of the satellite ellipsoid coordinate projected to the plane map coordinate system.        var ee = 0.00669342162296594323; //  ee: eccentricity of ellipsoid.        var dLat = this.transformLat(lng - 105.0, lat - 35.0);        var dLng = this.transformLng(lng - 105.0, lat - 35.0);        var radLat = lat / 180.0 * this.PI;        var magic = Math.sin(radLat);        magic = 1 - ee * magic * magic;        var sqrtMagic = Math.sqrt(magic);        dLat = (dLat * 180.0) / ((a * (1 - ee)) / (magic * sqrtMagic) * this.PI);        dLng = (dLng * 180.0) / (a / sqrtMagic * Math.cos(radLat) * this.PI);        return { 'lat': dLat, 'lng': dLng };    },    /**     * WGS-84 to GCJ-02     * @param {number} wgsLat      * @param {number} wgsLng      */    gcj_encrypt: function (wgsLat, wgsLng) {        if (this.outOfChina(wgsLat, wgsLng))            return { 'lat': wgsLat, 'lng': wgsLng };        var d = this.delta(wgsLat, wgsLng);        return { 'lat': wgsLat + d.lat, 'lng': wgsLng + d.lng };    },    /**     * GCJ-02 to WGS-84     * @param {number} gcjLat      * @param {number} gcjLng      */    gcj_decrypt: function (gcjLat, gcjLng) {        if (this.outOfChina(gcjLat, gcjLng))            return { 'lat': gcjLat, 'lng': gcjLng };        var d = this.delta(gcjLat, gcjLng);        return { 'lat': gcjLat - d.lat, 'lng': gcjLng - d.lng };    },    /**     * GCJ-02 to WGS-84 exactly     * @param {number} gcjLat      * @param {number} gcjLng      */    gcj_decrypt_exact: function (gcjLat, gcjLng) {        var initDelta = 0.01;        var threshold = 0.000000001;        var dLat = initDelta, dLng = initDelta;        var mLat = gcjLat - dLat, mLng = gcjLng - dLng;        var pLat = gcjLat + dLat, pLng = gcjLng + dLng;        var wgsLat, wgsLng, i = 0;        while (1) {            wgsLat = (mLat + pLat) / 2;            wgsLng = (mLng + pLng) / 2;            var tmp = this.gcj_encrypt(wgsLat, wgsLng)            dLat = tmp.lat - gcjLat;            dLng = tmp.lng - gcjLng;            if ((Math.abs(dLat) < threshold) && (Math.abs(dLng) < threshold))                break;            if (dLat > 0) pLat = wgsLat; else mLat = wgsLat;            if (dLng > 0) pLng = wgsLng; else mLng = wgsLng;            if (++i > 10000) break;        }        //console.log(i);        return { 'lat': wgsLat, 'lng': wgsLng };    },    /**     * GCJ-02 to BD-09     * @param {number} gcjLat      * @param {number} gcjLng      *      */    bd_encrypt: function (gcjLat, gcjLng) {        var x = gcjLng, y = gcjLat;        var z = Math.sqrt(x * x + y * y) + 0.00002 * Math.sin(y * this.x_pi);        var theta = Math.atan2(y, x) + 0.000003 * Math.cos(x * this.x_pi);        var bdLng = z * Math.cos(theta) + 0.0065;        var bdLat = z * Math.sin(theta) + 0.006;        return { 'lat': bdLat, 'lng': bdLng };    },    /**     * BD-09 to GCJ-02     * @param {*} bdLat      * @param {*} bdLng      */    bd_decrypt: function (bdLat, bdLng) {        var x = bdLng - 0.0065, y = bdLat - 0.006;        var z = Math.sqrt(x * x + y * y) - 0.00002 * Math.sin(y * this.x_pi);        var theta = Math.atan2(y, x) - 0.000003 * Math.cos(x * this.x_pi);        var gcjLng = z * Math.cos(theta);        var gcjLat = z * Math.sin(theta);        return { 'lat': gcjLat, 'lng': gcjLng };    },    //WGS-84 to Web mercator    //mercatorLat -> y mercatorLng -> x    mercator_encrypt: function (wgsLat, wgsLng) {        var x = wgsLng * 20037508.34 / 180.;        var y = Math.log(Math.tan((90. + wgsLat) * this.PI / 360.)) / (this.PI / 180.);        y = y * 20037508.34 / 180.;        return { 'lat': y, 'lng': x };        /*         if ((Math.abs(wgsLng) > 180 || Math.abs(wgsLat) > 90))         return null;         var x = 6378137.0 * wgsLng * 0.017453292519943295;         var a = wgsLat * 0.017453292519943295;         var y = 3189068.5 * Math.log((1.0 + Math.sin(a)) / (1.0 - Math.sin(a)));         return {'lat' : y, 'lng' : x};         //*/    },    // Web mercator to WGS-84    // mercatorLat -> y mercatorLng -> x    mercator_decrypt: function (mercatorLat, mercatorLng) {        var x = mercatorLng / 20037508.34 * 180.;        var y = mercatorLat / 20037508.34 * 180.;        y = 180 / this.PI * (2 * Math.atan(Math.exp(y * this.PI / 180.)) - this.PI / 2);        return { 'lat': y, 'lng': x };        /*         if (Math.abs(mercatorLng) < 180 && Math.abs(mercatorLat) < 90)         return null;         if ((Math.abs(mercatorLng) > 20037508.3427892) || (Math.abs(mercatorLat) > 20037508.3427892))         return null;         var a = mercatorLng / 6378137.0 * 57.295779513082323;         var x = a - (Math.floor(((a + 180.0) / 360.0)) * 360.0);         var y = (1.5707963267948966 - (2.0 * Math.atan(Math.exp((-1.0 * mercatorLat) / 6378137.0)))) * 57.295779513082323;         return {'lat' : y, 'lng' : x};         //*/    },    // two point's distance    distance: function (latA, lngA, latB, lngB) {        var earthR = 6371000.;        var x = Math.cos(latA * this.PI / 180.) * Math.cos(latB * this.PI / 180.) * Math.cos((lngA - lngB) * this.PI / 180);        var y = Math.sin(latA * this.PI / 180.) * Math.sin(latB * this.PI / 180.);        var s = x + y;        if (s > 1) s = 1;        if (s < -1) s = -1;        var alpha = Math.acos(s);        var distance = alpha * earthR;        return distance;    },    outOfChina: function (lat, lng) {        if (lng < 72.004 || lng > 137.8347)            return true;        if (lat < 0.8293 || lat > 55.8271)            return true;        return false;    },    transformLat: function (x, y) {        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));        ret += (20.0 * Math.sin(6.0 * x * this.PI) + 20.0 * Math.sin(2.0 * x * this.PI)) * 2.0 / 3.0;        ret += (20.0 * Math.sin(y * this.PI) + 40.0 * Math.sin(y / 3.0 * this.PI)) * 2.0 / 3.0;        ret += (160.0 * Math.sin(y / 12.0 * this.PI) + 320 * Math.sin(y * this.PI / 30.0)) * 2.0 / 3.0;        return ret;    },    transformLng: function (x, y) {        var 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 * this.PI) + 20.0 * Math.sin(2.0 * x * this.PI)) * 2.0 / 3.0;        ret += (20.0 * Math.sin(x * this.PI) + 40.0 * Math.sin(x / 3.0 * this.PI)) * 2.0 / 3.0;        ret += (150.0 * Math.sin(x / 12.0 * this.PI) + 300.0 * Math.sin(x / 30.0 * this.PI)) * 2.0 / 3.0;        return ret;    }};//WGS84 to GCj02GPS2Google2Baidu.WGS_84_to_GCJ_02 = GPS2Google2Baidu.gcj_encrypt;//GCJ02 to WGS84GPS2Google2Baidu.GCJ_02_to_WGS_84 = GPS2Google2Baidu.gcj_decrypt_exact;//Mars coordinate system (GCJ-02) to Baidu coordinate system (BD-09) GPS2Google2Baidu.GCJ_02_to_BD_09 = GPS2Google2Baidu.bd_encrypt;//Baidu coordinate system (BD-09) to Mars coordinate system (GCJ-02)GPS2Google2Baidu.BD_09_to_GCJ_02 = GPS2Google2Baidu.bd_decrypt;//Baidu coordinate system (BD-09) to WGS84GPS2Google2Baidu.BD_09_to_WGS_84 = function (lat, lng) {    var b2c = this.BD_09_to_GCJ_02(lat, lng);    return this.GCJ_02_to_WGS_84(b2c.lat, b2c.lng);}// WGS84 to Baidu coordinate system (BD-09)GPS2Google2Baidu.WGS_84_to_BD_09 = function (lat, lng) {    var w2c = this.WGS_84_to_GCJ_02(lat, lng);    return this.GCJ_02_to_BD_09(w2c.lat, w2c.lng);}export default GPS2Google2Baidu;

Topics: Front-end Javascript