openlayer加载百度离线地图坐标不准确问题

#ol加载百度离线地图坐标不准确问题
最近由于项目需要,在使用ol加载百度离线地图时候,发现通过ol加载的百度地图,显示的坐标不准确,请看下图
在百度坐标拾取系统获取到的天安门的坐标
通过ol加载的百度离线地图坐标
通过以上可以发现百度坐标拾取中获取到的天安门坐标是116.403119,39.912721,而ol加载的坐标确是116.4052,39.7240,纬度相差了0.2,偏差了很大,经过查看网上的一些资料,发现ol加载的默认坐标是EPSG:3857,如果为了显示经纬度直接在加载坐标时候直接写成EPSG:4326就会出现坐标偏差。猜想是不是EPSG:4326是84坐标,而百度是bd09坐标,经过网上查找的方法未果,后来看到网上的一篇博客,对百度原有的js进行了删减,利用百度的js创建新的坐标系,在加载时候使用百度坐标可以达到目的。废话少说,直接上js



var b2, a8 = b2 = a8 || {
	version: "1.3.4"
};
a8.guid = "$BAIDU$";
window[a8.guid] = window[a8.guid] || {};
a8.object = a8.object || {};
a8.extend = a8.object.extend = function(cM, T) {
	for (var cL in T) {
		if (T.hasOwnProperty(cL)) {
			cM[cL] = T[cL]
		}
	}
	return cM
};

window.BMap = window.BMap || {};
window.BMap.version = "1.3";
window.BMap._register = [];
window.BMap.register = function(T) {
	this._register.push(T)
};
window.BMap.apiLoad = window.BMap.apiLoad || function() {};

window._jsload = function(T, cL) {
	cA.run(T, cL)
};

function bu(T, cL) {
	this.x = T || 0;
	this.y = cL || 0
}
bu.prototype.equals = function(T) {
	return T && T.x == this.x && T.y == this.y
};

function cd(T, cL) {
	if (isNaN(T)) {
		T = bV(T);
		T = isNaN(T) ? 0 : T
	}
	if (b3(T)) {
		T = parseFloat(T)
	}
	if (isNaN(cL)) {
		cL = bV(cL);
		cL = isNaN(cL) ? 0 : cL
	}
	if (b3(cL)) {
		cL = parseFloat(cL)
	}
	this.lng = T;
	this.lat = cL
}
cd.isInRange = function(T) {
	return T && T.lng <= 180 && T.lng >= -180 && T.lat <= 74 && T.lat >= -74
};
cd.prototype.equals = function(T) {
	return T && this.lat == T.lat && this.lng == T.lng
};

function bd() {}
bd.prototype.lngLatToPoint = function() {
	throw "lngLatToPoint\u65b9\u6cd5\u672a\u5b9e\u73b0"
};
bd.prototype.pointToLngLat = function() {
	throw "pointToLngLat\u65b9\u6cd5\u672a\u5b9e\u73b0"
};

function ba() {}
ba.prototype = new bd();
a8.extend(ba, {
	EARTHRADIUS: 6370996.81,
	MCBAND: [12890594.86, 8362377.87, 5591021, 3481989.83,
		1678043.12, 0
	],
	LLBAND: [75, 60, 45, 30, 15, 0],
	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]
	],
	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
		]
	],
	getDistanceByMC: function(cP, cN) {
		if (!cP || !cN) {
			return 0
		}
		var cL, cO, T, cM;
		cP = this.convertMC2LL(cP);
		if (!cP) {
			return 0
		}
		cL = this.toRadians(cP.lng);
		cO = this.toRadians(cP.lat);
		cN = this.convertMC2LL(cN);
		if (!cN) {
			return 0
		}
		T = this.toRadians(cN.lng);
		cM = this.toRadians(cN.lat);
		return this.getDistance(cL, T, cO, cM)
	},
	getDistanceByLL: function(cP, cN) {
		if (!cP || !cN) {
			return 0
		}
		cP.lng = this.getLoop(cP.lng, -180, 180);
		cP.lat = this.getRange(cP.lat, -74, 74);
		cN.lng = this.getLoop(cN.lng, -180, 180);
		cN.lat = this.getRange(cN.lat, -74, 74);
		var cL, T, cO, cM;
		cL = this.toRadians(cP.lng);
		cO = this.toRadians(cP.lat);
		T = this.toRadians(cN.lng);
		cM = this.toRadians(cN.lat);
		return this.getDistance(cL, T, cO, cM)
	},
	convertMC2LL: function(cL) {
		var cM, cO;
		cM = new cd(Math.abs(cL.lng), Math.abs(cL.lat));
		for (var cN = 0; cN < this.MCBAND.length; cN++) {
			if (cM.lat >= this.MCBAND[cN]) {
				cO = this.MC2LL[cN];
				break
			}
		}
		var T = this.convertor(cL, cO);
		var cL = new cd(T.lng.toFixed(6), T.lat.toFixed(6));
		return cL
	},
	convertLL2MC: function(T) {
		var cL, cN;
		T.lng = this.getLoop(T.lng, -180, 180);
		T.lat = this.getRange(T.lat, -74, 74);
		cL = new cd(T.lng, T.lat);
		for (var cM = 0; cM < this.LLBAND.length; cM++) {
			if (cL.lat >= this.LLBAND[cM]) {
				cN = this.LL2MC[cM];
				break
			}
		}
		if (!cN) {
			for (var cM = this.LLBAND.length - 1; cM >= 0; cM--) {
				if (cL.lat <= -this.LLBAND[cM]) {
					cN = this.LL2MC[cM];
					break
				}
			}
		}
		var cO = this.convertor(T, cN);
		var T = new cd(cO.lng.toFixed(2), cO.lat.toFixed(2));
		return T
	},
	convertor: function(cM, cN) {
		if (!cM || !cN) {
			return
		}
		var T = cN[0] + cN[1] * Math.abs(cM.lng);
		var cL = Math.abs(cM.lat) / cN[9];
		var cO = cN[2] + cN[3] * cL + cN[4] * cL * cL + cN[5] * cL * cL * cL + cN[6] * cL * cL * cL * cL + cN[7] * cL * cL * cL * cL * cL + cN[8] * cL * cL * cL * cL * cL * cL;
		T *= (cM.lng < 0 ? -1 : 1);
		cO *= (cM.lat < 0 ? -1 : 1);
		return new cd(T, cO)
	},
	getDistance: function(cL, T, cN, cM) {
		return this.EARTHRADIUS * Math.acos((Math.sin(cN) * Math.sin(cM) + Math
			.cos(cN) * Math.cos(cM) * Math.cos(T - cL)))
	},
	toRadians: function(T) {
		return Math.PI * T / 180
	},
	toDegrees: function(T) {
		return (180 * T) / Math.PI
	},
	getRange: function(cM, cL, T) {
		if (cL != null) {
			cM = Math.max(cM, cL)
		}
		if (T != null) {
			cM = Math.min(cM, T)
		}
		return cM
	},
	getLoop: function(cM, cL, T) {
		while (cM > T) {
			cM -= T - cL
		}
		while (cM < cL) {
			cM += T - cL
		}
		return cM
	}
});
a8.extend(ba.prototype, {
	lngLatToMercator: function(T) {
		return ba.convertLL2MC(T)
	},
	lngLatToPoint: function(T) {
		var cL = ba.convertLL2MC(T);
		return new bu(cL.lng, cL.lat)
	},
	mercatorToLngLat: function(T) {
		return ba.convertMC2LL(T)
	},
	pointToLngLat: function(T) {
		var cL = new cd(T.x, T.y);
		return ba.convertMC2LL(cL)
	},
	pointToPixel: function(cL, cP, cO, cN, cQ) {
		if (!cL) {
			return
		}
		cL = this.lngLatToMercator(cL, cQ);
		var cM = this.getZoomUnits(cP);
		var T = Math.round((cL.lng - cO.lng) / cM + cN.width / 2);
		var cR = Math.round((cO.lat - cL.lat) / cM + cN.height / 2);
		return new bu(T, cR)
	},
	pixelToPoint: function(T, cS, cO, cM, cL) {
		if (!T) {
			return
		}
		var cR = this.getZoomUnits(cS);
		var cP = cO.lng + cR * (T.x - cM.width / 2);
		var cN = cO.lat - cR * (T.y - cM.height / 2);
		var cQ = new cd(cP, cN);
		return this.mercatorToLngLat(cQ, cL)
	},
	getZoomUnits: function(T) {
		return Math.pow(2, (18 - T))
	}
});

function aj(T, cL) {
	window.BMap[T] = cL
}

function b3(T) {
	return typeof T == "string"
}

aj("Point", cd);
aj("Pixel", bu);
aj("MercatorProjection", ba);

var projBD09 = new ol.proj.Projection({           
	code: 'BD:09',
    extent: [-20037726.37, -11708041.66, 20037726.37, 12474104.17],
    units: 'm',
    axisOrientation: 'neu',
    global: false         
});                  
ol.proj.addProjection(projBD09);      
ol.proj.addCoordinateTransforms("EPSG:3857", "BD:09",         
	function(coordinate) {
		return mercatortoBd09(coordinate[0], coordinate[1]);        
	},  
	function(coordinate) {          
		return bd09toMercator(coordinate[0], coordinate[1]);        
	}      
);
在这个js最后,创建了BD09坐标系,这样我们在创建鼠标位置时候就可以用BD09坐标系了,鼠标显示的位置也正确了。


var mousePositionControl = new ol.control.MousePosition({
	//坐标格式
	coordinateFormat: ol.coordinate.createStringXY(7),
	//地图投影坐标系(若未设置则输出为默认投影坐标系下的坐标)
	projection: 'BD:09',
	//坐标信息显示样式类名,默认是'ol-mouse-position'
	className: 'custom-mouse-position2',
	//显示鼠标位置信息的目标容器
	target: document.getElementById('mouse-position'),
	//未定义坐标的标记
	undefinedHTML: '&nbsp;'
});
/**
 * bd09 经纬度坐标转墨卡托坐标。注意这是引用了百度原生的坐标转换,需要对应引入百度离线地图偏移js
 * @author lanbizixunlu
 * @date 2019-11-21 14:00:21
 */
function bd09toMercator(lng,lat){
	if(lng==null||lng==""||lat==null||lat==""){return null;}
	var point= new BMap.MercatorProjection().lngLatToPoint(new BMap.Point(lng,lat));
	return [point.x,point.y];
}

/**
 * 从墨卡托坐标转bd09坐标 。注意这是引用了百度原生的坐标转换,需要对应引入百度离线地图偏移js
 * @author lanbizixunlu
 * @date 2019-11-21 14:13:00
 * @param {Object} x 
 * @param {Object} y
 */
function mercatortoBd09(x,y){
	if(x==null||x==""||y==null||y==""){return null;}
	var c=new BMap.MercatorProjection().pointToLngLat(new BMap.Pixel(x,y));
	return [c.lng,c.lat];
}

再次显示坐标,可以看到几乎差不多了。
在这里插入图片描述

本文如果有侵权,实属抱歉,我必删除此分享。闲暇总结下自己遇到的问题,只为技术交流,希望做ol的的小伙伴们都能互相分享大家遇到的难点,方便自己也方便别人。

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值