Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

百度、火星坐标、wgs84相互转换 #36

Open
liujiusheng opened this issue Sep 21, 2017 · 0 comments
Open

百度、火星坐标、wgs84相互转换 #36

liujiusheng opened this issue Sep 21, 2017 · 0 comments
Labels

Comments

@liujiusheng
Copy link
Owner

liujiusheng commented Sep 21, 2017

var pi = Math.PI,
	a = 6378245.0,
	ee = 0.00669342162296594323,
	x_pi = pi * 3000 / 180;

	
function outOfChina(lng, lat) {
	return (lng < 72.004 || lng > 137.8347) || (lat < 0.8293 || lat > 55.8271)
}


function transformLat(x, y) {
	var pi = Math.PI,
		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 * pi) + 20.0 * Math.sin(2.0 * x * pi)) * 2.0 / 3.0;
	ret += (20.0 * Math.sin(y * pi) + 40.0 * Math.sin(y / 3.0 * pi)) * 2.0 / 3.0;
	ret += (160.0 * Math.sin(y / 12.0 * pi) + 320 * Math.sin(y * pi / 30.0)) * 2.0 / 3.0;
	return ret;
}


function transformLng(x, y) {
	var pi = Math.PI,
		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 * pi) + 20.0 * Math.sin(2.0 * x * pi)) * 2.0 / 3.0;
	ret += (20.0 * Math.sin(x * pi) + 40.0 * Math.sin(x / 3.0 * pi)) * 2.0 / 3.0;
	ret += (150.0 * Math.sin(x / 12.0 * pi) + 300.0 * Math.sin(x / 30.0 * pi)) * 2.0 / 3.0;
	return ret;
}


function checkCoordinate(lng, lat) {
	if (arguments.length === 1 && lng instanceof Array) {
		lat = +lng[1];
		lng = +lng[0];
	} else {
		lng = +lng;
		lat = +lat;
	}
	if (isNaN(lng) || isNaN(lat)) {
		throw new Error('Invalid parameters');
	}
	return [lng, lat];
}


/**
 * WGS84坐标转GCJ02坐标
 * @param {number|Array} lng 经度值或经纬度数组
 * @param {number} [lat] 纬度值
 * @returns {Array<number>} 转换后的GCJ02经纬度数组
 */
function wgs2gcj(lng, lat) {
	var coord = checkCoordinate(lng, lat),
		gLng, gLat;
	lng = coord[0];
	lat = coord[1];
	if (outOfChina(lng, lat)) {
		gLng = lng;
		gLat = lat;
	} else {
		var dLat = transformLat(lng - 105.0, lat - 35.0),
			dLng = transformLng(lng - 105.0, lat - 35.0),
			radLat = lat / 180.0 * pi,
			magic = Math.sin(radLat);
		magic = 1 - ee * magic * magic;
		var sqrtMagic = Math.sqrt(magic);
		dLat = (dLat * 180.0) / ((a * (1 - ee)) / (magic * sqrtMagic) * pi);
		dLng = (dLng * 180.0) / (a / sqrtMagic * Math.cos(radLat) * pi);
		gLat = lat + dLat;
		gLng = lng + dLng;
	}
	return [gLng, gLat];
}


/**
 * GCJ02坐标转WGS84坐标
 * @param {number|Array} lng 经度值或经纬度数组
 * @param {number} [lat] 纬度值
 * @returns {Array<number>} 转换后的WGS84经纬度数组
 */
function gcj2wgs(lng, lat) {
	if (outOfChina(lng, lat)) {
		return [lng, lat]
	}
	else {
		var dlat = transformLat(lng - 105.0, lat - 35.0);
		var dlng = transformLng(lng - 105.0, lat - 35.0);
		var radlat = lat / 180.0 * 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) * pi);
		dlng = (dlng * 180.0) / (a / sqrtmagic * Math.cos(radlat) * pi);
		mglat = lat + dlat;
		mglng = lng + dlng;
		return [lng * 2 - mglng, lat * 2 - mglat]
	}
}


/**
 * GCJ02坐标转百度BD09坐标
 * @param {number|Array} lng 经度值或经纬度数组
 * @param {number} [lat] 纬度值
 * @returns {Array<number>} 转换后的BD09经纬度数组
 */
function gcj2bd(lng, lat) {
	var coord = checkCoordinate(lng, lat),
		x = coord[0],
		y = coord[1],
		z = Math.sqrt(x * x + y * y) + 0.00002 * Math.sin(y * x_pi),
		theta = Math.atan2(y, x) + 0.000003 * Math.cos(x * x_pi);
	return [
		z * Math.cos(theta) + 0.0065,
		z * Math.sin(theta) + 0.006
	];
}


/**
 * 百度DB09坐标转GCJ02坐标
 * @param {number|Array} lng 经度值或经纬度数组
 * @param {number} [lat] 纬度值
 * @returns {Array<number>} 转换后的GCJ02经纬度数组
 */
function bd2gcj(lng, lat) {
	var coord = checkCoordinate(lng, lat),
		x = coord[0] - 0.0065,
		y = coord[1] - 0.006,
		z = Math.sqrt(x * x + y * y) - 0.00002 * Math.sin(y * x_pi),
		theta = Math.atan2(y, x) - 0.000003 * Math.cos(x * x_pi);
	return [
		z * Math.cos(theta),
		z * Math.sin(theta)
	];
}

var gcj = bd2gcj(106.55803,29.569023);
console.log(gcj);
//[106.5515951464041,29.562730117201024]
console.log(gcj2wgs(gcj[0],gcj[1]));
//[106.54787750396565,29.565578928729394]

经纬度转Web墨卡托

function LonLat2WebMercator(lng, lat) {
            var x = (lng / 180.0) * 20037508.3427892;
            var y;
            if (lat > 85.05112) {
                lat = 85.05112;
            }
            if (lat < -85.05112) {
                lat = -85.05112;
            }
            y = (Math.PI / 180.0) * lat;
            var tmp = Math.PI / 4.0 + y / 2.0;
            y = 20037508.3427892 * Math.log(Math.tan(tmp)) / Math.PI;
            var result = {
                x: x,
                y: y
            };
            return result;
 }

Web墨卡托转经纬度

function mercatorTolonlat(mercator){
    var lonlat={x:0,y:0};
    var x = mercator.x/20037508.34*180;
    var y = mercator.y/20037508.34*180;
    y= 180/Math.PI*(2*Math.atan(Math.exp(y*Math.PI/180))-Math.PI/2);
    lonlat.x = x;
    lonlat.y = y;
    return lonlat;
}

百度经纬度bd09II转百度墨卡托bd09mc

var LLBAND =[75, 60, 45, 30, 15, 0];
    var LL2MC = [
        [-0.0015702102444, 111320.7020616939, 1704480524535203, -10338987376042340, 26112667856603880, -35149669176653700, 26595700718403920, -10725012454188240, 1800819912950474, 82.5],
        [0.0008277824516172526, 111320.7020463578, 647795574.6671607, -4082003173.641316, 10774905663.51142, -15171875531.51559, 12053065338.62167, -5124939663.577472, 913311935.9512032, 67.5],
        [0.00337398766765, 111320.7020202162, 4481351.045890365, -23393751.19931662, 79682215.47186455, -115964993.2797253, 97236711.15602145, -43661946.33752821, 8477230.501135234, 52.5],
        [0.00220636496208, 111320.7020209128, 51751.86112841131, 3796837.749470245, 992013.7397791013, -1221952.21711287, 1340652.697009075, -620943.6990984312, 144416.9293806241, 37.5],
        [-0.0003441963504368392, 111320.7020576856, 278.2353980772752, 2485758.690035394, 6070.750963243378, 54821.18345352118, 9540.606633304236, -2710.55326746645, 1405.483844121726, 22.5],
        [-0.0003218135878613132, 111320.7020701615, 0.00369383431289, 823725.6402795718, 0.46104986909093, 2351.343141331292, 1.58060784298199, 8.77738589078284, 0.37238884252424, 7.45]
    ];
    function getRange(cC, cB, T) {
        if (cB != null) {
            cC = Math.max(cC, cB);
        }
        if (T != null) {
            cC = Math.min(cC, T);
        }
        return cC;
    }
    function getLoop(cC, cB, T) {
        while (cC > T) {
            cC -= T - cB;
        }
        while (cC < cB) {
            cC += T - cB;
        }
        return cC;
    }


    function convertor(cC, cD) {
      if (!cC || !cD) {
        return null;
      }
      let T = cD[0] + cD[1] * Math.abs(cC.x);
      const cB = Math.abs(cC.y) / cD[9];
      let cE = cD[2] + cD[3] * cB + cD[4] * cB * cB +
        cD[5] * cB * cB * cB + cD[6] * cB * cB * cB * cB +
        cD[7] * cB * cB * cB * cB * cB +
        cD[8] * cB * cB * cB * cB * cB * cB;
      T *= (cC.x < 0 ? -1 : 1);
      cE *= (cC.y < 0 ? -1 : 1);
      return [T, cE];
    }


    function convertLL2MC(T) {
        let cD, cC, len;
        T.x = getLoop(T.x, -180, 180);
        T.y = getRange(T.y, -74, 74);
        const cB = T;
        for (cC = 0, len = LLBAND.length; cC < len; cC++) {
            if (cB.y >= LLBAND[cC]) {
                cD = LL2MC[cC];
                break;
            }
        }
        if (!cD) {
            for (cC = LLBAND.length - 1; cC >= 0; cC--) {
                if (cB.y <= -LLBAND[cC]) {
                    cD = LL2MC[cC];
                    break;
                }
            }
        }
        const cE = convertor(T, cD);
        return cE;
    }

百度墨卡托bd09mc转bd09II

var MCBAND = [12890594.86, 8362377.87, 5591021, 3481989.83, 1678043.12, 0];
    var MC2LL = [
      [1.410526172116255e-8, 0.00000898305509648872, -1.9939833816331, 200.9824383106796, -187.2403703815547, 91.6087516669843, -23.38765649603339, 2.57121317296198, -0.03801003308653, 17337981.2],
      [-7.435856389565537e-9, 0.000008983055097726239, -0.78625201886289, 96.32687599759846, -1.85204757529826, -59.36935905485877, 47.40033549296737, -16.50741931063887, 2.28786674699375, 10260144.86],
      [-3.030883460898826e-8, 0.00000898305509983578, 0.30071316287616, 59.74293618442277, 7.357984074871, -25.38371002664745, 13.45380521110908, -3.29883767235584, 0.32710905363475, 6856817.37],
      [-1.981981304930552e-8, 0.000008983055099779535, 0.03278182852591, 40.31678527705744, 0.65659298677277, -4.44255534477492, 0.85341911805263, 0.12923347998204, -0.04625736007561, 4482777.06],
      [3.09191371068437e-9, 0.000008983055096812155, 0.00006995724062, 23.10934304144901, -0.00023663490511, -0.6321817810242, -0.00663494467273, 0.03430082397953, -0.00466043876332, 2555164.4],
      [2.890871144776878e-9, 0.000008983055095805407, -3.068298e-8, 7.47137025468032, -0.00000353937994, -0.02145144861037, -0.00001234426596, 0.00010322952773, -0.00000323890364, 826088.5]
    ];


    function convertor(cC, cD) {
      if (!cC || !cD) {
        return null;
      }
      let T = cD[0] + cD[1] * Math.abs(cC.x);
      const cB = Math.abs(cC.y) / cD[9];
      let cE = cD[2] + cD[3] * cB + cD[4] * cB * cB +
        cD[5] * cB * cB * cB + cD[6] * cB * cB * cB * cB +
        cD[7] * cB * cB * cB * cB * cB +
        cD[8] * cB * cB * cB * cB * cB * cB;
      T *= (cC.x < 0 ? -1 : 1);
      cE *= (cC.y < 0 ? -1 : 1);
      return [T, cE];
    }
    

    function convertMC2LL(cB) {
      const cC = {
        x: Math.abs(cB.x),
        y: Math.abs(cB.y)
      };
      let cE;
      for (let cD = 0, len = MCBAND.length; cD < len; cD++) {
        if (cC.y >= MCBAND[cD]) {
          cE = MC2LL[cD];
          break;
        }
      }
      const T = convertor(cB, cE);
      return T;
    }

度分秒转十进制度

const data = [
    [`105°53'33.7056"`, `28°55'33.7007"`],
    [`105°50'48.3423"`, `28°56'42.5295"`],
    [`105°50'13.5311"`, `28°56'39.7392"`],
    [`105°49'19.8841"`, `28°56'42.5295"`],
    [`105°49'59.5704"`, `28°57'55.2528"`],
    [`105°51'7.0272"`, `28°59'32.2332"`],
    [`105°51'23.5979"`, `29°1'18.1812"`],
    [`105°51'27.6408"`, `29°1'22.206"`],
    [`105°52'37.2144"`, `29°1'55.4988"`],
    [`105°52'47.9216"`, `29°2'41.8178"`],
    [`105°52'47.9216"`, `29°2'40.4268"`],
    [`105°53'42.3707"`, `29°3'6.6960"`],
    [`105°55'49.7100"`, `29°3'31.2767"`],
    [`105°56'26.5847"`, `29°3'41.9652"`],
    [`106°4'38.4924"`, `29°5'0.6828"`],
    [`106°4'12.8604"`, `29°5'23.1468"`],
    [`106°6'46.4364"`, `29°3'39.3372"`],
    [`106°8'22.3727"`, `29°4'20.3124"`],
    [`106°8'59.4456"`, `29°12'24.5160"`],
    [`106°13'19.9487"`, `29°12'37.4292"`],
    [`106°14'3.6528"`, `29°14'31.0775"`],
    [`106°15'32.0663"`, `29°17'41.3084"`],
    [`106°19'51.222"`, `29°15'30.1644"`],
    [`106°23'41.5788"`, `29°17'37.5935"`],
    [`106°23'39.5808"`, `29°20'27.4199"`]
]

function DegreeConvertBack(value) { ///<summary>度分秒转换成为度</summary>
    var du = value.split("°")[0];
    var fen = value.split("°")[1].split("'")[0];
    var miao = value.split("°")[1].split("'")[1].split('"')[0];

    return Math.abs(du) + (Math.abs(fen) / 60 + Math.abs(miao) / 3600);
}

const arr = []
let stringsx = '';
let stringsy = '';
data.map(v => {
    const result = []
    v.map(a => {
        result.push(DegreeConvertBack(a))
    })
    arr.push(result)
    stringsx += result[0]+'\r\n';
    stringsy += result[1]+'\r\n';
})

console.log(stringsx);
console.log(stringsy);

参考

https://blog.csdn.net/qq_35771567/article/details/84766271

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

1 participant