Leaflet使用中经验总结

Leaflet使用中经验总结

标签:leaflet

1.Leaflet中使用复选框控制图层显示

​ Leaflet本身有图层控制的支持,但最近用Leaflet做台风的小项目,其中一个细节是使用复选框控制图层显示与否,解决方法作如下记录。在表格中的"选择”列是对应一个台风图层的复选框,通过勾选来展示和隐藏本图层。Leaflet中的图层有其所属的leaflet_id,是为了保证图层的唯一性,但要选中复选框来操作对应的图层,显然leaflet_id帮不上什么忙了。

​ 于是,在绘制图层时给图层绑定一个自定义的layerId

var id = 202002;
var lyr_point = L.circle(……);
var lyr_polyline = L.polyline(……);
var lyr = L.featureGroup([lyr_point,lyr_polyline]);
lyr.options.layerId = id; // 给图层(组)lyr绑定自定义id,在options参数里添加
批注 2020-07-14 154759.png

​ js创建复选框时,给每一个复选框绑定id,值即为对应台风的id。要展示图层时,查看当前选中复选框是否选中,若选中则根据id构造url绘制;要隐藏图层时,遍历图层组,若传入的id与某一个图层的layerId匹配,则隐藏该图层。复选框绑定的函数框架如下,这样就可以实现使用复选框控制图层了。

function showPath(id){
    if(document.getElementById(id.toString()).checked){
        //这里使用id构造url,利用返回的数据绘制图层
    }else{
        lyrGroup.eachLayer(function (layer){
            if(id == layer.options.LayersID){
                lyr.removeLayer(layer);
            }
        }
    }
}

[图片上传失败...(image-fac0aa-1594712751210)]

2.台风风圈的绘制

​ Leaflet中绘制台风风圈,网上有 一篇博客 实现的比较完整,具体思路是扩展L.Polygon类,使用SVG的path绘制。但我这里调用这个扩展类绘制的风圈不稳定,在地图缩放、拖动,窗口大小的改变都会是风圈图层消失。在浏览器中查看,发现上述操作是SVG的path里的d属性清零了,百思不得其解,于是乎放弃这个方法,改使用turf.js绘制风圈。

​ turf.js是浏览器和Node.js环境下的高级地理空间分析的js库,里面实现了很多常见的空间分析,比如缓冲区、点在多边形内等。我这里用lineArc函数,指定中心点、半径、起始和终止角度后,它可以绘制一段圆弧,注意这里的圆弧是由计算出来的很多点拟合而成的,并不是真正的绘制了一条圆弧。其中options参数中的step默认为64,如果想要展示效果更顺滑一点,可以选择拟合点数。

​ 分别指定东北,东南,西南,西北四个方向上的半径长度,单位默认是kilometer,生成四段圆弧,再把四段圆弧的坐标都push进一个数组,利用lineString函数生成线要素,再利用lineToPolygon函数转换为多边形。

​ 最后,使用L.geoJSON将风圈图层添加到地图上。实现函数贴在下方。

// p--中心点(包含四个方向的半径),lyr--风圈图层所添加进的图层组
function drawTyphoonCircle(p,lyr){
    var center = turf.point([p.longitude, p.latitude]);
    var r_ne,r_se,r_sw,r_nw;
    if(p.radius7_quad && p.radius7){    
        r_ne = p.radius7_quad.ne;
        r_se = p.radius7_quad.se;
        r_sw = p.radius7_quad.sw;
        r_nw = p.radius7_quad.nw;
    }else{
        return;
    }
    var options = {number:2048};
    var arc_ne = turf.lineArc(center, r_ne, 0, 89.9,options);
    var arc_se = turf.lineArc(center, r_se, 90, 179.9,options);
    var arc_sw = turf.lineArc(center, r_sw, 180, 269.9,options);
    var arc_nw = turf.lineArc(center, r_nw, 270, 360.1,options);

    var arcs = [];
    arcs.push(arc_ne,arc_se,arc_sw,arc_nw);

    var myStyle = {
        "color": "#ccffcc",
        "weight": 2,
        "fillColor":"#ccffcc"
    };

    var typhoonCircleCoords = [];
    for(var i=0;i<arcs.length;i++){
        var rawCoords1 = arcs[i].geometry.coordinates;

        for(var j=0;j<rawCoords1.length;j++){
            typhoonCircleCoords.push(rawCoords1[j]);
        }
    }

    var lineAll = turf.lineString(typhoonCircleCoords);
    var typhoonCirclePolygon = turf.lineToPolygon(lineAll);

    L.geoJSON(typhoonCirclePolygon,{style:myStyle}).addTo(lyr);
}

3.给表格添加滚动条,设置后无效

overflow-y设置为true后,要设置height为一个固定的值,比如600px。

4.Leaflet中加载Mapbox自定义地图

使用L.tileLayer创建,url template中的username是Mapbox的注册账户的用户名。在https://studio.mapbox.com/中自定义图层的分享按钮处点击,即可看到style_id和Access Token。

var mymap = L.map('map').setView([20.557212,126.402354],3.5);

L.tileLayer('https://api.mapbox.com/styles/v1/{username}/{style_id}/tiles/512/{z}/{x}/{y}?access_token={accessToken}',{
    username:'whitedreamer',
    style_id:'cjn64ahui0ycg2rq72fer5a3r',
    accessToken:'pk.eyJ1Ijoid2hpdGVkcmVhbWVyIiwiYSI6ImNqbjN4azFjcDAwbG0zcG52aGc3M2x0M2sifQ.CYsl1oXDVr1PWgx4z6lSeg'
}).addTo(mymap);

5.单击表格行等同于单击行内的复选框,选中图层

这个功能是问题1的改进版,需要修改原有的代码逻辑。首先,删除复选框的onclick绑定的事件,然后改写showPath函数:根据图层id(等同于checkbox的id)绘制台风路径,增加hidePath函数:根据图层id隐藏台风路径;最后,编写selectARow函数,获取所点击表格行中的复选框id,根据id判断图层是否已绘制,若未绘制则绘制该图层,若已绘制则取消绘制。

注意:selectARow函数根据id判断复选框是否被选中来判断图层是否已绘制,存在逻辑矛盾,因为点击复选框是点击就绘制,取消就取消绘制;而点击表格行是若未选中则选中后绘制,若选中了则取消选中然后取消绘制。这两个逻辑相反,无法调和,故采取上述逻辑。

function showPath(id){
    lyr_num += 1;//lyr_num是图层数量
        if(lyr_num > 4){
            alert('Layers More Than 4.');
        }

        var url = 'https://www.readearth.com/typhoon/'+id.toString().slice(0,4)+'/'+id+'.json';
        draw(url,id);
        $('.badge')[0].innerHTML=lyr_num;//bootstrap徽标,显示在按钮上,展示当前选中的图层数量
        ids.push(id);
}

function hidePath(id){
    lyr.eachLayer(function (layer){
        if(id == layer.options.LayersID){
            lyr.removeLayer(layer);
            lyr_num -= 1;
            $('.badge')[0].innerHTML=lyr_num;//更新当前显示的图层数量
        }
    });

    ids.forEach(function(item, index) {
        if(item == id) {
            ids.splice(index, 1);//删除id数组中的对应项
        }
    });
}

function selectARow(){
    $('.table').on('click','tr',function(){
        var td_checkbox = $(this)[0].children[3];//获取checkbox所在td
        var checkbox = td_checkbox.children[0];//获取checkox
        var id = parseInt(checkbox.id);//获取checkbox的id

        // flag标志行对应的图层是否已绘制,若已绘制则移除,若未绘制则绘制,默认未绘制
        var layers = lyr.getLayers();
        var flag = 0;
        if(layers.length){
            lyr.eachLayer(function(layer){
                if(id == layer.options.LayersID){
                    flag = 1;
                }
            })
        }
        if(flag){
            checkbox.checked = false;
            hidePath(id);  
        }else{
            checkbox.checked = true;
            showPath(id);
        }      
    })
}

6.一个div浮在一个div之上

假设div1在底下,div2浮在上方,则css应该这么写。注意:div1与div2之间是平行关系,不是嵌套关系,但div1定义要在div2之上。

#div1{
    position:absolute;
}

#div2{
    positon:relative;
    z-index:1/*div2的z-index大于div1的z-index即可,默认div1的z-index为0*/
}

7.Echarts绘制图表的依赖

从Echarts官网下载的官方案例会引入很多文件,一般的图表,像饼图、条形图、折线图等等,只需要引入一个文件,即:

 <!-- 引入echarts.js -->
<script type='text/javascript' src='https://cdn.bootcss.com/echarts/4.2.1-rc1/echarts.min.js'></script>

推荐下载下来本地引用,在线引用速度略慢。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 202,980评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,178评论 2 380
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 149,868评论 0 336
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,498评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,492评论 5 364
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,521评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,910评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,569评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,793评论 1 296
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,559评论 2 319
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,639评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,342评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,931评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,904评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,144评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,833评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,350评论 2 342