百度地图坐标转换服务封装(优化批量并发异步访问)

本人接触网页地图以来已有5年之窗,与百度地图打交道少说也有3年以上了,百度坐标转换从最开始的只支持单组坐标转换到现在的批量转换(限制每次100组),而且是无规律的算法纠偏,根本不好复制这种算法到本地进行转换,每次只能乖乖的ajax get到百度服务接口返回结果。

这种做法对于单组坐标的转换体验上影响不大,但是当我们需要纠偏的坐标量很多的时候,按正常的写法ajax异步请求,而且每次最多只能传入100组坐标,只能分批来调,而且是异步处理,还要定义一堆全局变量记住状态值,代码量多且复杂,项目大就难以管理了。

今天终于让我想出了一个优化的解决办法,对这个服务进行封装,闭包内进行异步方法递归,把回调方法传递到最后结果那一处执行并返回结果对象。废话不多说了,直接亮代码,写的不好处欢迎提意见!

baidu.maps.convertor.js文件:

/**
 *! 百度地图坐标转换接口
 *! 支持从gps(真实)坐标、google坐标、soso坐标等转换为百度坐标
 *! 传入百度坐标对象,返回纠偏后的百度坐标对象,注意要在百度地图api环境下调用
 */
(function() {

	var _BAIDU_KEY_ = "xxxxxx";   // 请填写您申请的密钥
	var point_count = [];
	var res = [];

	var convertor = (function() {

		return {
			translate: translate
		};

		/**
		 *  point 为百度的坐标对象,可以是单个坐标对象,也可以为多个坐标对象的数组
		 *  type取值:
		 *  1:GPS设备获取的角度坐标;
			2:GPS获取的米制坐标、sogou地图所用坐标;
			3:google地图、soso地图、aliyun地图、mapabc地图和amap地图所用坐标
			4:3中列表地图坐标对应的米制坐标
			5:百度地图采用的经纬度坐标
			6:百度地图采用的米制坐标
			7:mapbar地图坐标;
			8:51地图坐标
			返回:
			回调函数:function(res) { }
			res为坐标对象的数组,单组坐标纠偏直接这样取:res[0]
		 */
		function translate(point, type, fn) {
			var coordarr = [];
			if(Object.prototype.toString.call(point) === "[object Array]") {
				// 多个坐标的数组
				$.map(point, function(position) {
					coordarr.push(position);
				});
			} else {
				// 单个坐标
				coordarr.push(point);
			}

			var n = res.length;
			/**
			 *! 这里使用二维数组存储结构集,给每一个调用赋予独立索引,
			 *! 为了防止批量调用异步请求时全局对象被最后一次执行的结果替换
			 */
			res[n] = [];
			point_count[n] = 0;
			reqgeoconv(coordarr, type, fn, n, 0);
		}

		function reqgeoconv(coords, type, fn, n, reqCount) {
			point_count[n] = coords.length;
			var list = [];
	        for (var i = reqCount; i < reqCount + 100; i++) {	// (限制:每次最多支持100个)
	            if (i >= point_count[n])
	                break;
	            list.push(coords[i].lng + "," + coords[i].lat);
	        }

			var url = [];
			url.push("http://api.map.baidu.com/geoconv/v1/?");
			url.push("coords=");
			url.push(list.join(";"));
			url.push("&ak=");
			url.push(_BAIDU_KEY_);
			url.push("&from=");
			url.push(type);
			url.push("&to=5");
			url.push("&callback=?");

			$.getJSON(url.join(""), 
	            function(data) {
	                if (data.status === 0) {
	                	$.map(data.result, function(bcoord) {
	                		res[n].push(new BMap.Point(bcoord.x, bcoord.y));
	                	});
	                	var included = res[n].length;
	                	if(included < point_count[n]) {
	                		reqgeoconv(coords, type, fn, n, included);	// 递归异步方法,循环到有结果为止
	                	} else {
	                		fn(res[n]);
	                	}
	                }
	            });
		}

	}());

	window['baidumap'] = window['baidumap'] || {};
	window['baidumap']['convertor'] = convertor;

}());

var baidu = baidu || {};
baidu.maps = window['baidumap'];


 引用了以上脚本之后,你的业务类可以这样调用: 

var paths = [ 
	new BMap.Point(116.343532, 23.552301),
	new BMap.Point(116.108865, 23.446878),
	new BMap.Point(116.332589, 23.986241),
	new BMap.Point(116.223445, 23.899533)
];
baidu.maps.convertor.translate(paths, 1, function(res) {
      $.map(res, function(p) {
          // your code...
  	  });
});

当然对于只是单组坐标这样调用就可以了:

baidu.maps.convertor.translate(new BMap.Point(113.663445, 24.789533), 1, function(res) {
      var point = res[0];
      // your code...
});


已标记关键词 清除标记
©️2020 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页