一步一步开发电商平台 区域广告实现
技术需求描述:
(1)以北京市为例,以北京市中心点坐标为原点,创建类表格覆盖物,表格代表的宽高均代表一公里。每一块单元格都有自己的编号。
- 格式 html+js 地图为百度地图
- 兼容性 ie6+ 以及其他主流浏览器支持
- 以市中心坐标点为中心区块的中心点
- 以数学的x,y轴坐标系,作为区块编号命名的依据
- 每一个区块都是一个正方形,宽高都是一公里
- 地图及上面的表格覆盖物能放大缩小
- 遮罩层的每个方块都可以点击,点击后方块变深色,再次点击恢复原色,并可以记录点击的那个区块。
- 能以字符串或数组,初始化覆盖物表格中的已选中区块
- 能将地图中心点定位到某一点(百度地图支持),相关的覆盖物对应显示
- 能根据配置,设置覆盖物的大小(n*m个方块)和每一个区块的大小(之前提到的宽高1公里可设置)
(2) 相应的JavaScript API
ClearAllArea() 作用清空所有以选中的区块
ClickArea() 点击区块后执行的函数
InitArea(str,bool)初始化区域
参数说明:str 字符串,格式为01_12,23_11 已选中的区块
Bool bool类型,true或false ,true 代表初始化的区块可再次点击编辑,false 代表初始化的区块不可编辑(区块颜色区分正常其他颜色)。
/* 这块本来想外包出去,当时主要忙于支付模块的开发,没人接,最后还是自己搞。
技术实现:
利用百度地图API中的自定义覆盖物实现
单个自定义的覆盖物可以满足一个区块的所有功能,对于那么多区块怎么办,循环产生多个区块让他们一个挨着一个。功能就实现了。
(这块有一个性能问题,因为每一个区块都是一个对象,都要消耗内存和计算资源,这样会使浏览器占用大量内存,还有每次对地图的缩放都会使这些区块全部重绘。所以区块的数量要进行限制。900个区块(30*30)的时候浏览器就很卡了)
// 定义自定义覆盖物的构造函数 function SquareOverlay(x,y,center,color,eve){ this._latPer=0.008998; this._lngPer=0.011711; this._name=x+"_"+y; this._x=x;//x坐标索引 this._y=y; //y坐标索引 this._center = center; this._length = length; this._color = color; this._minLng = center.lng - this._lngPer / 2+ x * this._lngPer; this._maxLng = center.lng + this._lngPer / 2+ x * this._lngPer; this._minLat = center.lat - this._latPer / 2+ y * this._latPer; this._maxLat = center.lat + this._latPer / 2+ y * this._latPer; } // 继承API的BMap.Overlay SquareOverlay.prototype = new BMap.Overlay(); // 实现初始化方法 SquareOverlay.prototype.initialize = function (map) { // 保存map对象实例 this._map = map; // 创建div元素,作为自定义覆盖物的容器 var div = document.createElement("div"); div.name = this._name; div.style.position = "absolute"; var maxPixel = map.pointToOverlayPixel(new BMap.Point(this._maxLng, this._maxLat)); var minPixel = map.pointToOverlayPixel(new BMap.Point(this._minLng, this._minLat)); div.style.width = Math.abs(maxPixel.x - minPixel.x) + "px"; div.style.height = div.style.width; //Math.abs(maxPixel.y-minPixel.y) + "px"; div.style.backgroundColor = this._color; //填充颜色 div.style.filter = "alpha(opacity=55)"; //透明度兼容ie8 div.style.opacity = 0.55; //透明度 div.style.border = "1px solid #6390ff"; //设置边框和 边框颜色 div.onclick = AreaClick; // 将div添加到覆盖物容器中 map.getPanes().floatPane.appendChild(div); // 保存div实例 this._div = div; // 需要将div元素作为方法的返回值,当调用该覆盖物的show、 // hide方法,或者对覆盖物进行移除时,API都将操作此元素。 return div; } // 实现绘制方法 SquareOverlay.prototype.draw = function(){ // 根据地理坐标转换为像素坐标,并设置给容器 var leftposition= this._map.pointToOverlayPixel(new BMap.Point(this._minLng,this._maxLat)); var maxPixel=this._map.pointToOverlayPixel(new BMap.Point(this._maxLng,this._maxLat)); var minPixel=this._map.pointToOverlayPixel(new BMap.Point(this._minLng,this._minLat)); this._div.style.left = leftposition.x + "px"; this._div.style.top = leftposition.y + "px"; this._div.style.width =Math.abs(maxPixel.x-minPixel.x) + "px"; this._div.style.height =Math.abs(maxPixel.y-minPixel.y) + "px"; }
/* 实现中点击事件的绑定 刚开始 使用 传方法名,然后动态调用。但有问题,单独触发事件时 没问题,放在for循环中 就有问题,最后改为固定的方法名。