那些坑儿系列--Javascript--1--百度地图 api

最近在找最方便的年检地,但是有地址,却无法直观判断。各种地图应用也没有自定义多点显示。遂自己找了百度地图api写了个自定义多点显示的页面。碰到点坑,记录一下,分享一下。如果看官们觉的不错,或者有用,请留个爪印鼓励鼓励或者指出不足,也不枉我花时间写这么老半天。:)

环境:win10 1609 , 浏览器:Edge,ie,chrome

目录

坑一:跨域

坑二:BMap.Geocoder 和 BMap.LocalSearch

坑三:InfoWindow 信息窗口和 SearchInfoWindow 搜索信息窗口

坑四:异步回调与循环


坑一:跨域

       api文档要求,引入格式为:

<script type="text/javascript" src="http://api.map.baidu.com/api?v=2.0&ak=你的key"></script>

       由于是本地用js写的一个页面,Edge直接不允许执行,在不改变安全配置的基础上,几乎无解,而且无论如何该页面,均会出错,最终放弃。

       chrome的console中,一直出现错误

A parser-blocking, cross site (i.e. different eTLD+1) script, http://api.map.baidu.com/getscript?v=2.0&ak=你的key信息&services=&t=20181212102408, is invoked via document.write. The network request for this script MAY be blocked by the browser in this or a future page load due to poor network connectivity. If blocked in this page load, it will be confirmed in a subsequent console message. See https://www.chromestatus.com/feature/5718547946799104 for more details.

查了一下,是跨域错误,点进错误链接中看见这个src指向的脚本:

(function(){ window.BMap_loadScriptTime = (new Date).getTime(); document.write('<script type="text/javascript" src="http://api.map.baidu.com/getscript?v=2.0&ak=你的key&services=&t=20181212102408"></script>');})();

由于用的document.write 重写脚本位置,造成chrome跨域错误。

搜索了一下网上信息,觉得最方便的就是直接将src改为脚本中的指向,但是发现t的值和别人教导的不同,遂采用自己获取到的src更改:

<script type="text/javascript" src="http://api.map.baidu.com/getscript?v=2.0&ak=你的key&services=&t=20181212102408"></script>

chrome中黄膏药一样的警告信息终于没了,清爽。


坑二:BMap.Geocoder 和 BMap.LocalSearch

网上搜索的多点显示样例,用的是LocalSearch,搜索的另一个教程,用的是Geocoder 。

花了点功夫,找官方文档研究了一下,总结使用场景如下:

如果有详细地址,比如XX路XX弄XX号 ,建议使用Geocoder

如果是地标名称啥的,比如天安门,金茂大厦,使用LocalSearch

由于我写的东西,是有详细地址的,所以该使用Geocoder


坑三:InfoWindow 信息窗口和 SearchInfoWindow 搜索信息窗口

一般教程文章中,使用的InfoWindow,样子及其土

想要百度自带的那种样式,

有个教程提到,注意用了不同的api,一开始,我只注意到,两个标准例子之间,第二个新增加了2个引用 

<script type="text/javascript" src="http://api.map.baidu.com/library/SearchInfoWindow/1.5/src/SearchInfoWindow_min.js"></script>
<link rel="stylesheet" href="http://api.map.baidu.com/library/SearchInfoWindow/1.5/src/SearchInfoWindow_min.css" />

天真的以为,只是引用的不同,改了半天的options

{
	title  : "百度大厦",      //标题
	width  : 290,             //宽度
	height : 105,              //高度
	panel  : "panel",         //检索结果面板
	enableAutoPan : true,     //自动平移
	searchTypes   :[
		BMAPLIB_TAB_SEARCH,   //周边检索
		BMAPLIB_TAB_TO_HERE,  //到这里去
		BMAPLIB_TAB_FROM_HERE //从这里出发
	]
}

毛用没有,一直显示土样,翻了官方的api文档,这些options不在InfoWindowOptions中啊。火一大,2个例子文本直接放到BC中比较,才发现,狗日的,根本用的不是InfoWindow。

用的是BMapLib.SearchInfoWindow。这个SearchInfoWindow在百度地图api文档的类说明中根本没有,在百度API中才有。

百度地图api的demo中也不重点标注一下。

传送门:

纯文本的信息窗口 , 带检索功能的信息窗口


坑四:异步回调与循环

百度地图api的DEMO中,批量地址解析(传送门:批量地址解析),用的是setTimeout 400ms 全局变量实现的回调循环。样例中,用全局变量进行控制。复杂点的程序,这种控制比较难受。而且这种setTimeout,不能做到尽快完成。测试了一下,最低在100ms中,就会乱。

1、用同样的代码写到我的程序中,chrome调试的时候console总是出错,数组index溢出。发现Demo代码本身就不严谨,肯定会溢出。

function bdGEO(){
	var add = adds[index];
	geocodeSearch(add);
	index++;
}
function geocodeSearch(add){
	if(index < adds.length){
		setTimeout(window.bdGEO,400);
	} 

index的最大值本来就是adds.length-1 ,index小于长度就继续search,最后值一定index溢出。

改为: index < adds.length -1

2、该程序主要用2个函数互相调用的方式,每搜索一次,就延迟400ms继续搜索。既然互相调用,直接在回调中加入调用得了。

为了防止某个地址堵死,仍旧保留setTimeout,改程序如下:

    var t;
	function bdGEO(){
		var add = adds[index];
		geocodeSearch(add);
		index++;
	}
	function geocodeSearch(add){
		if(index < adds.length-1){
        //保留setTimeout的id
			t=setTimeout(window.bdGEO,400);
		} 
		myGeo.getPoint(add, function(point){
			if (point) {
				document.getElementById("result").innerHTML +=  index + "、" + add + ":" + point.lng + "," + point.lat + "</br>";
				var address = new BMap.Point(point.lng, point.lat);
				addMarker(address,new BMap.Label(index+":"+add,{offset:new BMap.Size(20,-10)}));
			}
          //回调在400ms内,则直接调用。
          clearTimeout(t);
          window.bdGEO();
		}, "合肥市");
	}

速度快了一大截。但是仍然出现隐患(网络堵塞,回调时间超过400ms)。

3、这种解决方式非常不好,全局变量,难以控制。网上搜啊搜啊,在一个官方帖子中有人提到闭包。nnd涉及闭包从来都头疼。头疼也要看啊。瞅啊瞅啊,终于瞅懂一点,改造改造,直接用循环解决。

代码我就粗略写一下:

function bdGEO(){
   	for(var i=0 ; i< adds.length ; i ++){
       	var add = adds[i];
       	//闭包,想保留什么数据,直接填在括号里面,j,addr为参数名
       	(function(j,addr){
           	myGeo.getPoint(add,function(point){
               	if (point) {
					document.getElementById("result").innerHTML +=  j + "、" + addr + ":" + point.lng + "," + point.lat + "</br>";
					var address = new BMap.Point(point.lng, point.lat);
					addMarker(address,new BMap.Label(j+":"+addr,{offset:new BMap.Size(20,-10)}));
		    	}
           	},"合肥市");
       	//注意 i,add 是外层的数据
       	})(i,add);
   	}
}

如果没必要保存顺序号,基本就完美了。如果要保存顺序号,可考虑事后排序问题,就不深入了。

 

 

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值