一、使用百度地图API的原因
之前一直在用和Robert Harm一起开发的Maps Marker Pro插件,优点是极其强大,想要的各种功能都有了,但缺点也很明显,由于众所周知的原因,国内谷歌地图处于残废状态,OpenStreetMap卡得要命,必应地图简陋又龟速,导致加载了Mapsmarker的页面响应极其缓慢,整合多个地图的页面尤其糟糕,严重影响使用体验。
感谢 @随望淡思 ,他的博文《用百度地图API做个人足迹地图教程》给了我不少启发,进而使用百度地图API重做了“足迹”页面,达到了自己想要的效果。
二、代码及修订
原始代码及安装过程见 @随望淡思 文,不再赘述。使用过程中发现一些问题和不足,综合查阅百度地图API后逐个解决。特分享如下:
1、在网速较慢,图片未加载时,生成的信息框高度比图片的总高度小,导致图片部分被隐藏。
此问题百度地图官方文档有写。代码如下:
marker.addEventListener("click", function() {
infoWindow.setContent(content);
this.openInfoWindow(infoWindow);
document.getElementById('imgDemo').onload = function (){
infoWindow.redraw(); //即onload时重绘弹出窗口
}
});
2、如何在同一个页面加载双地图?
解决方法百度地图官方也有说明,但比较简略。我自己整理的代码如下:
(1)<body></body>中插入两个层:
<div id="map1_container" >
<h2 class="post-title" style="text-align:center">World</h2>
<div id="allmap1"></div>
</div>
<hr>
<div id="map2_container">
<h2 class="post-title" style="text-align:center">China</h2>
<div id="allmap2"></div>
</div>
(2)</html>下方插入js:
<script type = "text/javascript" >
/* 创建 Map1 */
var map1 = new BMap.Map("allmap1"); //创建Map实例1
var point1 = new BMap.Point(8.858654,20.426204); //创建点坐标
var mapType1 = new BMap.MapTypeControl({mapTypes: [BMAP_NORMAL_MAP,BMAP_HYBRID_MAP],anchor: BMAP_ANCHOR_TOP_RIGHT}); //创建普通2D地图和卫星地图,放置在右上角
var overView1 = new BMap.OverviewMapControl(); //增加放大缩小及平移控件
var overViewOpen1 = new BMap.OverviewMapControl({isOpen:true, anchor: BMAP_ANCHOR_BOTTOM_RIGHT});
map1.centerAndZoom(point1, 1); //初始化地图,设置中心点坐标和地图级别
/* 创建 Map2 */
var map2 = new BMap.Map("allmap2"); //创建Map实例2
var point2 = new BMap.Point(106.744719,34.308185); //创建点坐标
var mapType2 = new BMap.MapTypeControl({mapTypes: [BMAP_NORMAL_MAP,BMAP_HYBRID_MAP],anchor: BMAP_ANCHOR_TOP_RIGHT}); //创建普通2D地图和卫星地图,放置在右上角
var overView2 = new BMap.OverviewMapControl(); //增加放大缩小及平移控件
var overViewOpen2 = new BMap.OverviewMapControl({isOpen:true, anchor: BMAP_ANCHOR_BOTTOM_RIGHT});
map2.centerAndZoom(point2, 5); //初始化地图,设置中心点坐标和地图级别
</script>
3、如何一键回到最初的位置?
读者在点了几个地标后容易迷失方向,想要回到最初的位置,只能鼠标滚半天……解决方法是在图上增加一个自定义控件“⊕”并加入如下代码。
/* 定义一个控件实现点击后回到原位置 Map1 */
function ZoomControl1(){
//设置默认停靠位置和偏移量
this.defaultAnchor = BMAP_ANCHOR_TOP_LEFT;
this.defaultOffset = new BMap.Size(23, 210);
}
//通过JavaScript的prototype属性继承于BMap.Control
ZoomControl1.prototype = new BMap.Control();
//自定义控件必须实现initialize方法,并且将控件的DOM元素返回
//在本方法中创建个div元素作为控件的容器,并将其添加到地图容器中
ZoomControl1.prototype.initialize = function(map1){
//创建一个DOM元素
var div = document.createElement("div");
//添加文字说明
div.appendChild(document.createTextNode("⊕"));
//设置样式
div.style.color = "#4369d0";
div.style.cursor = "pointer";
div.style.border = "1px solid gray";
div.style.backgroundColor = "whitesmoke";
//绑定事件
div.onclick = function(e){
map1.reset(); //reset图层为原始位置
}
//添加DOM元素到地图中
map1.getContainer().appendChild(div);
//将DOM元素返回
return div;
}
//创建控件实例
var myZoomCtrl1 = new ZoomControl1();
然后在创建Map的时候加上:
map1.addControl(myZoomCtrl1); //自定义控件添加到地图当中
4、怎样使用自定义图标?
百度地图官方文档如下:
function addMarker(point, index){ //创建图标对象
var myIcon = new BMap.Icon("markers.png", new BMap.Size(23, 25), {
//指定定位位置。
//当标注显示在地图上时,其所指向的地理位置距离图标左上
//角各偏移10像素和25像素。您可以看到在本例中该位置即是
//图标中央下端的尖角位置。
anchor: new BMap.Size(10, 25),
//设置图片偏移。
//当您需要从一幅较大的图片中截取某部分作为标注图标时,您
//需要指定大图的偏移位置,此做法与css sprites技术类似。
imageOffset: new BMap.Size(0, 0 - index * 25) // 设置图片偏移
});
//创建标注对象并添加到地图
var marker = new BMap.Marker(point, {icon: myIcon});
map.addOverlay(marker);
}
如果想要稍复杂一点,比如“我去过的地方用默认图标,我想去的地方用自定义图标”,我的代码如下:
var pt = new BMap.Point(lng, lat);
var myIcon = new BMap.Icon("icon/baiduOrangeIcon.png", new BMap.Size(20,28), {anchor: new BMap.Size(10, 28), infoWindowAnchor: new BMap.Size(10, 0)}); //自定义标注图标,注意添加anchor、infoWindowAnchor消除偏移
if(name.indexOf("想去") == -1) { //此处是在地标名字中加了“(想去)”二字,凡是有此二字的,判定为想去的地方并加载自定义图标
var marker = new BMap.Marker(pt); //创建标注
map1.addOverlay(marker); //将标注添加到地图中
}
else {
var marker = new BMap.Marker(pt,{icon:myIcon}); //自定义创建标注
map1.addOverlay(marker); //将标注添加到地图中
}
5、原代码里,文章超链接、图片都为空时出现错误图标。
解决方法:添加两段if-else函数。
if (web != 0)
var webtxt = "<a style='color:#888' href="+web+">"+name+"</a>"; //如果地名有超链接到文章,显示之
else
var webtxt = name; //否则只显示地名
if (pic1 != 0)
var content = "<div style='font-size:14px;max-width:220px;word-wrap:break-word;overflow:visible'><img src="+pic1+" style='width:220px;' id='imgDemo'><p/>"+webtxt+"<p/>"+year+"</div>"; //如果有图片,显示之
else
var content = "<div style='min-height:100%;max-width:220px;font-size:14px'>"+webtxt+"<p/>"+year+"</div>"; //否则不显示,解决<img src="空">时显示错误的问题
6、设置地标阴影及动画
阴影:
var pt = new BMap.Point(lng, lat);
var myIcon = new BMap.Icon("/icon/baiduBlueIcon.png", new BMap.Size(20,28), {anchor: new BMap.Size(10, 28), infoWindowAnchor: new BMap.Size(10, 0)});
var shadow1 = new BMap.Icon("/icon/shadow.png", new BMap.Size(20,28), {anchor: new BMap.Size(8, 26)});
var marker = new BMap.Marker(pt,{icon:myIcon, shadow:shadow1});
动画:
marker.addEventListener("click", function() {
marker.setAnimation(BMAP_ANIMATION_DROP);
}
7、设置省份高亮 [2019/4/30 更新]
有简单办法也有复杂办法。这里只举最简单的例子。
/* 创建高亮省份 */
madeBoundary();
//区域图
function madeBoundary() {
var datas = new Array("北京","上海","广东","江苏");
var bdary = new BMap.Boundary();
for(var i=0;i<datas.length;i++){
getBoundary1(datas[i],bdary);
}
}
//设置省份区域图
function getBoundary1(data,bdary){
data = data.split("-");
bdary.get(data[0], function(rs){ //获取行政区域
var count = rs.boundaries.length; //行政区域的点有多少个
var pointArray = [];
for (var i = 0; i < count; i++) {
var ply = new BMap.Polygon(rs.boundaries[i], {strokeWeight: 2, strokeColor: "#ff0000",fillOpacity:0.5,fillColor:"#fbd8d8"}); //建立多边形覆盖物
map2.addOverlay(ply); //添加覆盖物
}
});
}
三、百度足迹地图优缺点
优点:
- 加载速度飞快。
- 可使用百度地图坐标拾取系统搜索中文地名获取经纬度,偏僻的地儿也能秒找,非常方便。
- 配色清新,与“不存在”的谷歌地图有“异曲同工”之妙。
缺点:
- 手工修改页面新增地名的方法非常原始。像我一样有上百个地标的,简直做到要怀疑人生。
- 国外地名全部抓瞎,地标严重不全。
四、两种足迹地图的对比
目前最好用也是最全面的足迹地图插件仍然非Mapsmarker莫属,建议有需要的博主至此处下载。
对速度有需求、主要行踪集中在国内且有一定JS代码基础的博主,可选用百度地图的代码并自己制作。
Mapsmarker截屏:
百度地图截屏:
2019年6月23日
昨晚开始百度地图开始限制最大视图:
真的好恶心啊!换回Mapsmarker!
厉害
@fooleap呃,承蒙大神老弟夸赞,实在受之有愧……
加加油,争取把世界地图染红。
@从良未遂那我可能会累死……
钻研精神可嘉 😅
@bigfa过奖了,瞎折腾
红满全球指日可待
@maie“指日”还是很困难的,人生还有四十年……