一步一步开发电商平台 区域广告实现

技术需求描述:

(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循环中 就有问题,最后改为固定的方法名。  

 

posted @ 2015-08-17 13:11  未煮熟的虾  阅读(314)  评论(0编辑  收藏  举报