使用GeoHey SDK开发地图应用的那些小技巧(叁)

刚刚过完春节,面对节后综合症和“每逢佳节胖三斤”的双重打击,懒散的吃瓜群众依然沉溺于吃吃吃不能自拔。但是,活儿就在那里,你不去做,活也会来找你。所以即便再想念那还没吃够的肉和甜点,笔者依然被同事拖出来按在电脑前,一顿胖揍后鼻青脸肿的继续码字……

咳咳,回归正题,让我们继续来看本期的3个实例。

1.如何使一个图层在不同比例尺下显示不同的要素?

在处理这个需求时,我们需要依赖对地图比例尺的变化这一事件的监听,因此首先添加对“ zoomEnd”事件的监听,参看下面的伪代码

var map,event;
map.bind("zoomEnd",event);

添加监听后,我们就要针对AB两种情况分别处理了,先看情况A。

在A中,由于不同比例尺下,显示的内容中没有重复的要素。因此可以选择以下两个方案:
A-1:每次比例尺变动后,需要改变内容时,清空图层并将新的内容添加进去

var map, graphicLayer;
var gList = [[a,b,c],[d,e,f]];

map.bind("zoomEnd",replaceElement);

var replaceElement = function(){
    var res = map.getResolution();
    if(res<20){
        graphicLayer.clear();
        for(var i=0;i<gList[0].length;i++){
            var g = gList[0][i];
            g.addTo(graphicLayer);
        }
    }
    else(res>=20){
        graphicLayer.clear();
        for(var i=0;i<gList[1].length;i++){
            var g = gList[1][i];
            g.addTo(graphicLayer);
        }
    }
}

示例代码以比例尺20作为分段值,表示当地图处于小于20的比例尺,和大于等于20的比例尺,这两种情况下的不同表示。
但是,这种写法有一个问题,就是如果地图在缩放时,缩放前的比例尺和缩放后的比例尺中显示的内容,并没有变化,那也就不需要清空图层并重新添加要素,因此伪代码改进如下:

var map, graphicLayer;
var gList = [[a,b,c],[d,e,f]];
var oldRes;

map.bind("zoomStart",getOldRes);
map.bind("zoomEnd",replaceElement);

var getOldRes = function(){
    var oldRes = map.getResolution();
}
var replaceElement = function(){
    var res = map.getResolution();
    if(res<20 && oldRes>=20){
        graphicLayer.clear();
        for(var i=0;i<gList[0].length;i++){
            var g = gList[0][i];
            g.addTo(graphicLayer);
        }
    }
    else(res>=20 && oldRes <20){
        graphicLayer.clear();
        for(var i=0;i<gList[1].length;i++){
            var g = gList[1][i];
            g.addTo(graphicLayer);
        }
    }
    else{
        return;
    }
}

这样改进后,在缩放后如果不需要进行图层内容的改动,就不会触发清空重绘的代码,大大减少了不需要的绘制压力。

此外,如果不是以比例尺,而是是缩放等级来进行显示内容断定的话,需要自己加入一个比例尺-缩放等级的对照表,并在事件中进行换算,才能实现本需求。

2.在问题1点基础上,如果显示的是数据上图做出来的可视化成果?

思路与显示要素时的方法没有太大区别,只需要在替换图层内容时,重新设定tileLayer的url即可,调用setUrl方法后,sdk会自动刷新tileLayer,需要再做别的工作了。伪代码如下:

var map, tileLayer;
var tileUrls = [urlA,urlB];
var oldRes;

map.bind("zoomStart",getOldRes);
map.bind("zoomEnd",replaceElement);

var getOldRes = function(){
    var oldRes = map.getResolution();
}
var replaceElement = function(){
    var res = map.getResolution();
    if(res<20 && oldRes>=20){
        tileLayer.setUrl(tileUrls[0])
    }
    else(res>=20 && oldRes <20){
        tileLayer.setUrl(tileUrls[1])
    }
    else{
        return;
    }
}

3.在请求数据时,如果数据量过大,怎么获取全部数据?
通过GeoHery极海的在线平台请求数据时,每次请求返回的最大数据量是有一个上限的,1000个。但是对于地理大数据,不超过1000条的数据才是少数。当数据量较大时,一般情况下,我们推荐用户选择使用数据上图来显示数据,但是,如果是一定要获取的话,可以通过每次获取一个比1000小的长度,在请求时,请求比这个长度多1的大小,通过返回的数组长度与长度+1的值进行比较,来判断是否还有剩余没有获取的数据,有的话。再通过偏移量来进行循环获取剩下的部分。以下是实现的伪代码:


var len = 800, offset = 0;
var gList = [];

var getData = function(offset){
    $.ajax({
        url: requestUrl,
        type:get,
        data:{
            offset:offset,
            limit:len+1
        },
        success:function(data){
            if(data.code ==0){
                if(data.data.length >= (len+1)){
                    //还有数据需要再次进行循环
                    for(var i=0;i<len;i++){ 
                         gList.push(data.data[i]);
                    }
                    offset = offset + len;
                    getData(offset);
                }
                else{
                     for(var i=0;i<data.data.length;i++){ 
                         gList.push(data.data[i]);
                    }
                    //所有数据获取完成
                }
            }else{
              //出现错误
            }
        },
        error: function(err){
              //出现错误
        }
    });
}

$.ajax({
    url:,
    type:get,
    data:
})

本期的3个实例就到此结束。从下一期开始,我们将会为大家带来GeoHey SDK与热门流行的前端框架的结合使用。在这个“框架遍地走,一望挑花眼”的时代,作为走在行业前沿的诸位观众老爷,在与前端技术的结合上,也要跟上脚步,引领潮流。

对我们的SDK在使用上有问题的同学,可以先访问我们的示例页面,在其中进行在线调试。如果依然有问题,也可以关注我们的公众号,或是加入我们的QQ交流群(164183186)。