`
jjxliu306
  • 浏览: 159393 次
  • 性别: Icon_minigender_1
  • 来自: 西安
社区版块
存档分类
最新评论

Openlayers扩展H5绘制10W+数据

    博客分类:
  • GIS
阅读更多

本文基于openlayers2现有api扩展html5的支持绘制10W+的四边形,当然样式简单死板,只为说明通过H5

可以为ol带来不菲的性能(默认自带vector图层中添加feature超过2K+数据后就会出现卡顿)

 

-- 2017-04-13 :GridLayer.Source天假bc属性为格子边框颜色,如果存在边框颜色则绘制边框

 

废话不多说直接上代码,

 

 

 

1、创建一个对象,标明每个待绘制元素的基本信息,目前主要包含左上和右下的经纬度还有待显示的颜色:

/**

 * Class: GridLayer.Source

创建一个数据源的类型,一个格子中需要包含左上右下的经纬度还有要显示的颜色

 */ 

 

GridLayer = {};

 

/**

 * Class: GridLayer.Source

 */

GridLayer.Source = OpenLayers.Class({

 

  /** 

   *  左上经纬度

   * {OpenLayers.LonLat} 左上经纬度

   */

  l: null,

 

  /**

   * 栅格右下角经纬度

   */

  r:null ,

  

  /**

   * 栅格显示颜色

   */

  c:null ,

  

  /**

   *  边框显示颜色

   */

  bc:null,

  

  initialize: function(leftLonLat, rightLonLat ,color,boderColor ) {

    this.l = leftLonLat;

    this.r = rightLonLat;

    this.c = color ;

    this.bc = boderColor;

  },

 

  CLASS_NAME: 'GridLayer.Source'

});

 

/**

 * Class: GridLayer.Layer

 *  栅格图层

 * Inherits from:

 *  - <OpenLayers.Layer>

 */

GridLayer.Layer = OpenLayers.Class(OpenLayers.Layer, {

 

 

 

  /** 

   * Property: 所有的格点信息

   * {Array(<GridLayer.Source>)} internal coordinate list

   */

  points: null,

 

  

  /** 

   * Property: H5画布

   * {DOMElement} Canvas element.

   */

  canvas: null,

 

 

  /**

   * Constructor: GridLayer.Layer

   * Create a GridLayer layer.

   *

   * Parameters:

   * name - {String} Name of the Layer

   * options - {Object} Hashtable of extra options to tag onto the layer

   */

  initialize: function(name, options) {

    OpenLayers.Layer.prototype.initialize.apply(this, arguments);

    this.points = [];

     

    this.canvas = document.createElement('canvas');

    this.canvas.style.position = 'absolute';

    

    // For some reason OpenLayers.Layer.setOpacity assumes there is

    // an additional div between the layer's div and its contents.

    var sub = document.createElement('div');

    sub.appendChild(this.canvas);

    this.div.appendChild(sub);

  },

 

   

 

  /**

   * APIMethod: addSource

   * 添加一个格子元素

   *

   * Parameters:

   * source - {<GridLayer.Source>} 

   */

  addSource: function(source) {

    this.points.push(source);

  },

  

  /**

   * 添加所有的数据源

   */

  putSource: function(sources) {

 this.points =  sources ;

  },

  

  clear:function() {

 

 this.points = [];

  },

 

  /**

   * 删除一个格子元素

   * Parameters:

   * source - {<GridLayer.Source>} 

   */

  removeSource: function(source) {

    if (this.points && this.points.length) {

      OpenLayers.Util.removeItem(this.points, source);

    }

  },

 

  /** 

   * Method: moveTo

   * 地图移动时候回重绘地图,主要方法

   * Parameters:

   * bounds - {<OpenLayers.Bounds>} 

   * zoomChanged - {Boolean} 

   * dragging - {Boolean} 

   */

  moveTo: function(bounds, zoomChanged, dragging) {

 

    OpenLayers.Layer.prototype.moveTo.apply(this, arguments);

 

    if (dragging)

      return;

 

    //偏移

    var someLoc = new OpenLayers.LonLat(0,0);

    var offsetX = this.map.getViewPortPxFromLonLat(someLoc).x -

                  this.map.getLayerPxFromLonLat(someLoc).x;

    var offsetY = this.map.getViewPortPxFromLonLat(someLoc).y -

                  this.map.getLayerPxFromLonLat(someLoc).y;

 

    var w = this.map.getSize().w;

    var h = this.map.getSize().h ;

    

    this.canvas.width = w;

    this.canvas.height = h;

 

    var ctx = this.canvas.getContext('2d');

 

    ctx.save(); // Workaround for a bug in Google Chrome

    ctx.fillStyle = 'transparent';

    ctx.fillRect(0, 0, w, h);

    ctx.restore();

     

    

    

    //得出当前画布的左上右下经纬度数据 对于超过这个界限的数据 当前画布忽略绘制

    var left = new OpenLayers. Pixel(0,0);

    var right = new OpenLayers. Pixel(w,h);

    

    var leftlonlat = this.map.getLonLatFromPixel(left);

    var rightlonlat = this.map.getLonLatFromPixel(right);

    

    for (var i in this.points) {

 

      var src = this.points[i];

      

      //判断数据是否已经超越当前canvas 如果超越 直接跳过

      if(src.r.lon < leftlonlat.lon || src.r.lat > leftlonlat.lat

     || src.l.lon > rightlonlat.lon || src.l < rightlonlat .lat) {

     

     continue;

      }

     

      //坐标

      var leftpos = this.map.getLayerPxFromLonLat(src.l);

      var rightpos = this.map.getLayerPxFromLonLat(src.r);

      

      if(leftpos == null || rightpos == null) continue ;

       

      var minlon = leftpos.x ;

      var maxlat = leftpos.y;

      

      var maxlon = rightpos.x;

      var minlat = rightpos.y;

      

     

      var x = maxlon - minlon  ;

      var y = minlat - maxlat   ;

      

      //颜色

      //判断是否为shuzi  

      ctx.fillStyle= src.c;

      ctx.fillRect(minlon + offsetX ,maxlat + offsetY,x ,y  );

      ctx.fillStyle = 'transparent';

      //判断是否有边框颜色,如果有则绘制边框

      if(src.bc) {

     //border

     ctx.strokeStyle = src.bc ;

     ctx.strokeRect(minlon + offsetX ,maxlat + offsetY,x ,y  );

          ctx.strokeStyle = 'transparent';

     

      }

     

    }

 

     var dat = ctx.getImageData(0, 0, this.canvas.width, this.canvas.height);

   

 

    ctx.putImageData(dat, 0, 0); 

 

    

    this.canvas.style.left = (-offsetX) + 'px';

    this.canvas.style.top = (-offsetY) + 'px';

  },

 

  /** 

   * 图层extent 

   * Returns:

   * {<OpenLayers.Bounds>}

   */

  getDataExtent: function () {

    var maxExtent = null;

        

    if (this.points && (this.points.length > 0)) {

      var maxExtent = new OpenLayers.Bounds();

      for(var i = 0, len = this.points.length; i < len; ++i) {

        var point = this.points[i];

        maxExtent.extend(point.l);

      }

    }

 

    return maxExtent;

  },

 

  CLASS_NAME: 'GridLayer.Layer'

 

});

 

3、  调用

调用的时候直接引用后提供带渲染的数据即可,例如:

 

var gridLayer = new GridLayer.Layer("grid");

        var index = 0 ;

//循环经度

        for(var i  = 120 ; i<121.1 ; i+=0.002) {

              

               var lon = i;

               //循环纬度

               for(var j = 30 ; j < 30.5 ; j+=0.002) {

                     

                      var lat = j ;

                     

                      var leftlonlat = new OpenLayers.LonLat(lon,lat);

                      //根据中心点偏移左上和右下

                      var rightlonlat = new OpenLayers.LonLat(lon + 0.001, lat -  0.001);

                      //坐标系

                      leftlonlat.transform(map.displayProjection, map.projection);

                      rightlonlat.transform(map.displayProjection, map.projection);

                     

                      //一个datasource

                      var grid = new GridLayer.Source(leftlonlat, rightlonlat , '#FF0000' );

                      gridLayer.addSource(grid);

                      index++;

               }

              

        }

        console.log('size : ' + index);

        //设置图层透明度

        gridLayer.setOpacity(0.5);

        //加入map

        map.addLayer(gridLayer);

4、  说明

实际使用中数据如果从后台查询过来的话可能加载不了这么大的数据量,另外实际业务中的应用一般比这个复杂,此次扩展主要针对应用简单的业务(和我们当前公司业务很类似,N多个经纬度直接打在地图上,按照规则渲染颜色)。

5、 实际效果如图:



 

  • 大小: 37.6 KB
0
0
分享到:
评论

相关推荐

    室内矢量地图

    在实现室内地图时,通常会结合JavaScript库,如Leaflet或OpenLayers,它们提供了丰富的API接口和插件,便于开发人员进行地图操作、事件处理、图层管理等功能。例如,用户可以轻松地实现地图的拖拽、缩放、标记添加...

    HTML5教程及OpenStreetMap数据

    4. **Canvas画布**:`&lt;canvas&gt;`元素提供了一个JavaScript API,允许动态绘制图形,广泛用于游戏、数据可视化和图像处理。 5. **SVG矢量图**:支持内联SVG图形,提供清晰、可缩放的矢量图像,适用于各种分辨率的设备...

    html5基于cesium.js库的3d立体地球仪模型动画代码.zip

    "plugin"可能是包含自定义扩展或插件的文件夹,这些插件可能增强了cesium.js库的原有功能,例如添加特定的交互行为、特效或者数据加载策略。开发者可以通过阅读和理解这些插件的代码,学习如何自定义和扩展cesium.js...

    html5_3d地球

    这可能需要用到地理编码服务,以及额外的JavaScript库,如Leaflet或OpenLayers,它们提供了丰富的地图操作和地理数据处理功能。 总之,“html5_3d地球”是一个综合性的HTML5示例,展示了WebGL在创建交互式3D内容上...

Global site tag (gtag.js) - Google Analytics