需求
百度地图离线应用,网络上大部分都是不能切换地图的离线,只能根据配置文件填写一个类型;网上搜了一下没有这块添加类似在线版的可切换地图类型,使用官网的加载控件方式直接调用在线数据;不可行;网上搜了一款用QT实现的,想自己实现一个JS的,一样可以适用。
目前此版只对V2版离线做了实现。
代码
// ------------------------------------
// 自定义地图控件
// --------------------------------
/**
* 自定义地图类型切换
* @param {Object} bdmapcfg 离线地图配置参数
*/
function MapTypeControl(bdmapcfg){
this.bdmapcfg = bdmapcfg;
//console.log('container', this.bdmapcfg);
// 设置默认停靠位置和偏移量
this.defaultAnchor = BMAP_ANCHOR_TOP_RIGHT;
this.defaultOffset = new BMap.Size(10, 10);
}
//通过JavaScript的prototype属性继承于BMap.Control
MapTypeControl.prototype = new BMap.Control();
// 自定义控件必须实现自己的initialize方法,并且将控件的DOM元素返回
// 在本方法中创建个div元素作为控件的容器,并将其添加到地图容器中
MapTypeControl.prototype.initialize = function(map){
var self = this;
// 创建一个DOM元素
var div = document.createElement("div");
div.id="type-control";
// 设置样式
div.style.cursor = "pointer";
div.style.width="70%";
div.style.height="30px";
div.style.margin="10px 0px";
var childNodes = [{name:"卫星",value:'satemap'},{name:"普通",value:'normalmap'}];
childNodes.forEach(function(divNode, idx){
//子div
var childDiv=document.createElement('div');
childDiv.value=divNode.value;
childDiv.style.width="35px";
childDiv.style.height="20px";
childDiv.style.background="#FFFFFF";
childDiv.style.float="right";
childDiv.style.margin="0px";
childDiv.style.fontSize="12px";
childDiv.style.textAlign="center";
if(idx === 0) {
childDiv.style.borderRadius="0 3px 3px 0";
childDiv.style.borderBottom="thin solid #8EA8E0";
childDiv.style.borderRight="thin solid #8EA8E0";
childDiv.style.borderTop="thin solid #8EA8E0";
} else if(idx === (childNodes.length -1)) {
childDiv.style.borderRadius="3px 0 0 3px";
childDiv.style.borderBottom="thin solid #8EA8E0";
childDiv.style.borderLeft="thin solid #8EA8E0";
childDiv.style.borderTop="thin solid #8EA8E0";
}
childDiv.addEventListener('click', function(){
//console.log(this.parentNode);
self.changeMapType(this.value);
this.parentNode.childNodes.forEach(function(nd){
//console.log(nd.id);
nd.style.background="#FFFFFF";
nd.style.color="#000000";
});
this.style.background="#8EA8E0";
this.style.color="#FFFFFF";
this.style.fontWeight="bold";
});
//console.log(self.bdmapcfg['map_type'], divNode.value, (self.bdmapcfg['map_type'] == divNode.value));
if(self.bdmapcfg['map_type'] === divNode.value) {
childDiv.style.background="#8EA8E0";
childDiv.style.color="#FFFFFF";
childDiv.style.fontWeight="bold";
}
childDiv.appendChild(document.createTextNode(divNode.name));
div.appendChild(childDiv);
});
// 添加DOM元素到地图中
map.getContainer().appendChild(div);
// 将DOM元素返回
return div;
};
MapTypeControl.prototype.changeMapType = function(type){
var self = this;
if(self.bdmapcfg['map_type'] !== type) {
self.bdmapcfg['map_type'] = type;
//console.log(this);
//console.log('this->需在地图类型', type);
if(type === 'satemap') {
self.bdmapcfg.imgext = '.png'; //瓦片地图后缀
self.bdmapcfg.tiles_dir = self.bdmapcfg.home+'satemap'; //瓦片图目录
} else {
self.bdmapcfg.imgext = '.png'; //瓦片地图后缀
self.bdmapcfg.tiles_dir = self.bdmapcfg.home+'tiles'; //瓦片图目录
}
self.loadJScript();
}
};
MapTypeControl.prototype.loadJScript = function(){
var self = this;
var script = document.createElement("script");
script.type = "text/javascript";
script.src = self.bdmapcfg.home+"baidumap_offline_v2_20160921_min.js";
document.body.appendChild(script);
map = null;
initMap();
};
var map,zoomInt=8;
function initMap(){
// 百度地图API功能
map = new BMap.Map("map_demo"); // 创建Map实例
map.centerAndZoom(new BMap.Point(117.003586,36.67173), zoomInt); // 初始化地图,设置中心点坐标和地图级别
//map.addControl(new BMap.MapTypeControl()); //添加地图类型控件 离线只支持电子地图,卫星/三维不支持
//map.setCurrentCity("北京"); // 设置地图显示的城市 离线地图不支持!!
map.enableScrollWheelZoom(true); //开启鼠标滚轮缩放
map.addControl(new BMap.NavigationControl()); //缩放按钮
// 添加自定义控件
map.addControl(new MapTypeControl(bdmapcfg));
map.addEventListener("zoomend", function(){
zoomInt = this.getZoom();
//alert("地图缩放至:" + this.getZoom() + "级");
});
}
initMap();
涉及信息
方案重点:使用百度自定义控件方式,添加多DIV,通过鼠标事件重新生成Map对象;
资料信息:
- 离线版百度地图,网上一搜很多的。这里就不提供了。
- 官方自定义控件介绍:http://lbsyun.baidu.com/index.php?title=jspopular/guide/widget
- 参考的QT版实现:传送门
截图
卫星图:
普通图:
因为我参考了官方的配色,为了区分,截取了官方示例: