leaflet官网sample学习笔记+灾害情感地图实现(完结)

之所以写leaflet样例代码的博客,是因为想记录自己学习过程,提供一个笔记方便回头来看。
为什么要学leaflet?前面学了很久的 ArcGIS API for JS 虽功能齐全样式炫酷,但对于我这样的前端初学者来说十分不友好,并且他对geojson格式的处理也十分僵硬,sample没法改没法学。偶然间发现leaflet对geojson格式的处理很全,有官方sample也有其他人写的样例可以参考,于是做好了重新学习的准备。

在这片博客里,我把官方sample里的各种信息全部换成我熟悉的地点进行调试。我写代码喜欢写很多注释,写成自己最能理解的中文,方便回头看。所以文章可能没多少字,但是精华其实都在注释里了。

另,初学者(比如我)很不喜欢只有部分代码片的博客,因此本文贴出的代码片都是可以直接运行的。
本文以网盘形式给出了我本科毕业设计的情感地图部分的全部代码,数据来自于3.30-4.14的“凉山火灾”新浪微博,有需可自取。

毕业设计成品

经过两个星期的学习,我完成了毕业设计的情感地图设计部分。数据来源是2019.3.30-2019.4.14期间“凉山火灾”话题下的共3329条新浪微博,设计效果如图所示:

情感地图-全国情感地图-四川
在这里插入图片描述在这里插入图片描述
灾中(3.30-4.07)情感地图-全国灾中(3.30-4.07)情感地图-四川
在这里插入图片描述在这里插入图片描述
灾后(4.08-4.14)情感地图-全国灾后(4.08-4.14)情感地图-四川
在这里插入图片描述在这里插入图片描述

附上所有源码的链接:
链接:https://pan.baidu.com/s/14LlPPZp7uW65Dk-KAnogbQ
提取码:wpax

 

以下部分是对leaflet官网sample的学习笔记。源码也在网盘链接里,可直接运行。

Leaflet Quick Start Guide

https://leafletjs.com/examples/quick-start/

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>My First Guide Test</title>

    <!-- 官网让加的第一个-->
    <link rel="stylesheet" href="https://unpkg.com/leaflet@1.4.0/dist/leaflet.css"
          integrity="sha512-puBpdR0798OZvTTbP4A8Ix/l+A4dHDD0DGqYW6RQ+9jxkRFclaxxQb/SJAWZfWAkuyeQUytO7+7N4QKrDh+drA=="
          crossorigin=""/>

    <!-- 官网让加的第二个-->
    <!-- Make sure you put this AFTER Leaflet's CSS -->
    <script src="https://unpkg.com/leaflet@1.4.0/dist/leaflet.js"
            integrity="sha512-QVftwZFqvtRNi0ZyCtsznlKSWOStnDORoefr1enyq5mVL4tmKB3S/EnC3rRJcxCPavG10IcrVGSmPh6Qw5lwrg=="
            crossorigin=""></script>

</head>
<body>
    <!--地图想加在哪,下句就加在哪-->
    <!--<div id="mapid" style="width: 600px; height: 400px;"></div>-->
    <!--让地图占满屏幕(被注释掉的是官方代码)-->
    <div id="mapid" style="width: 100%; height: 100%;position: absolute"></div>
<script>

    //实例化地图mymap。坐标给的是武汉大学计算机大楼。后面那个参数是初始缩放比例,如果是1,就是一个世界地图
    //setview()调用返回一个map对象
    var myMap = L.map('mapid').setView([30.529422, 114.350413], 17);
    L.tileLayer('https://api.tiles.mapbox.com/v4/{id}/{z}/{x}/{y}.png?access_token={accessToken}', {
        attribution: 'Map data &copy; <a href="https://www.openstreetmap.org/">OpenStreetMap</a> contributors, <a href="https://creativecommons.org/licenses/by-sa/2.0/">CC-BY-SA</a>, Imagery © <a href="https://www.mapbox.com/">Mapbox</a>',
        maxZoom: 18,
        id: 'mapbox.streets',
        //accessToken是去官网https://account.mapbox.com/access-tokens/申请的默认公共token
        accessToken: 'pk.eyJ1Ijoid2xtcWppeWl6aCIsImEiOiJjanNwZ29zcTUwOXA5NGFveHEwNmNzZWgxIn0.rf8H02a7Z-PSV9qz471Cww'
    }).addTo(myMap);

//以上部分都可以直接拿去用的
//------------------------------------------分割线------------------------------------------------------------------------
    

    //增加一个marker在武汉大学计算机大楼
    var myMarker = L.marker([30.529422, 114.350413]).addTo(myMap);
    myMarker.bindPopup("<b>HELLO WORLD!!!</b><br>这里是武汉大学计算机大楼").openPopup();//openPopup只能在marker中使用


    //增加一个circle在国软菜地
    //第一个参数是圆心坐标,第二个参数可以定义各种属性
    var mycircle = L.circle([30.530651, 114.350102], {
        color: 'red',
        fillColor: '#EEEE00',
        fillOpacity: 0.5,
        radius: 60
    }).addTo(myMap);
    mycircle.bindPopup("你点击了国软菜地");


    //增加了一个多边形polygon在国软c3宿舍
    var mypolygon = L.polygon([
            [30.529441, 114.34927],
            [30.529459, 114.349844],
            [30.529348, 114.349861],
            [30.529307, 114.349292]
        ],{
        color: 'blue',
        fillColor: '##B0E0E6',
        fillOpacity: 0.5
    }).addTo(myMap);
    mypolygon.bindPopup("你点击了国软c3宿舍");


    //增加一个点击事件,点击地图任意地方,弹出点击点的坐标
    var myPopup=L.popup();
    function onMapClick(e) {
        myPopup
            .setLatLng(e.latlng)
            .setContent("你点击了坐标为" + e.latlng.toString()+"的点。")
            .openOn(myMap);
    }
    myMap.on('click', onMapClick);

</script>

</body>
</html>

实际效果:
在这里插入图片描述

用自定义的Icon图片做marker

https://leafletjs.com/examples/custom-icons/

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>My First Guide Test</title>

    <!-- 官网让加的第一个-->
    <link rel="stylesheet" href="https://unpkg.com/leaflet@1.4.0/dist/leaflet.css"
          integrity="sha512-puBpdR0798OZvTTbP4A8Ix/l+A4dHDD0DGqYW6RQ+9jxkRFclaxxQb/SJAWZfWAkuyeQUytO7+7N4QKrDh+drA=="
          crossorigin=""/>

    <!-- 官网让加的第二个-->
    <!-- Make sure you put this AFTER Leaflet's CSS -->
    <script src="https://unpkg.com/leaflet@1.4.0/dist/leaflet.js"
            integrity="sha512-QVftwZFqvtRNi0ZyCtsznlKSWOStnDORoefr1enyq5mVL4tmKB3S/EnC3rRJcxCPavG10IcrVGSmPh6Qw5lwrg=="
            crossorigin=""></script>

</head>
<body>
<!--地图想加在哪,下句就加在哪-->
<!--<div id="mapid" style="width: 600px; height: 400px;"></div>-->
<!--让地图占满屏幕(被注释掉的是官方代码)-->
<div id="mapid" style="width: 100%; height: 100%;position: absolute"></div>
<script>

    //实例化地图mymap。坐标给的是武汉大学计算机大楼。后面那个参数是初始缩放比例,如果是1,就是一个世界地图
    //setview()调用返回一个map对象
    var myMap = L.map('mapid').setView([30.529422, 114.350413], 17);
    L.tileLayer('https://api.tiles.mapbox.com/v4/{id}/{z}/{x}/{y}.png?access_token={accessToken}', {
        attribution: 'Map data &copy; <a href="https://www.openstreetmap.org/">OpenStreetMap</a> contributors, <a href="https://creativecommons.org/licenses/by-sa/2.0/">CC-BY-SA</a>, Imagery © <a href="https://www.mapbox.com/">Mapbox</a>',
        maxZoom: 18,
        id: 'mapbox.streets',
        //accessToken是去官网https://account.mapbox.com/access-tokens/申请的默认公共token
        accessToken: 'pk.eyJ1Ijoid2xtcWppeWl6aCIsImEiOiJjanNwZ29zcTUwOXA5NGFveHEwNmNzZWgxIn0.rf8H02a7Z-PSV9qz471Cww'
    }).addTo(myMap);


    //添加自定义icon三连
    var myLeafIcon = L.Icon.extend({//先添加一个阉割过的模板
        options:{
            shadowUrl : 'src/diamond-shadow.png',//影子的图片地址,地址记得加文件夹名字
            iconSize:     [38, 95],//图标大小
            shadowSize:   [50, 64],//影子大小
            iconAnchor:   [22, 94],//相对位置,我也不太懂
            shadowAnchor: [4, 62],
            popupAnchor:  [-3, -76]
        }
    })

    var myGreenDiamond =new myLeafIcon({iconUrl : 'src/diamond-green.png'});//一次实例化一个模板
    var myRedDiamond=new myLeafIcon({iconUrl : 'src/diamond-red.png'});//两次选定不同的icon值

    L.marker([30.52981, 114.352849],{icon:myGreenDiamond}).bindPopup('绿色的是信部三食堂').addTo(myMap);
    L.marker([30.529977, 114.355756],{icon:myRedDiamond}).bindPopup('红色的是信操').addTo(myMap);
    //与默认marker不一样的地方就是marker()里除了坐标外多加一个icon类型的参数


</script>

</body>
</html>

阿里巴巴在线icon库

本例中icon图标(存在源文件src路径下):
在这里插入图片描述
实际效果:
在这里插入图片描述

在Leaflet中使用geoJSON数据

https://leafletjs.com/examples/geojson/

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>JSON真香</title>
    <!-- 官网让加的第一个-->
    <link rel="stylesheet" href="https://unpkg.com/leaflet@1.4.0/dist/leaflet.css"
          integrity="sha512-puBpdR0798OZvTTbP4A8Ix/l+A4dHDD0DGqYW6RQ+9jxkRFclaxxQb/SJAWZfWAkuyeQUytO7+7N4QKrDh+drA=="
          crossorigin=""/>
    <!-- 官网让加的第二个-->
    <!-- Make sure you put this AFTER Leaflet's CSS -->
    <script src="https://unpkg.com/leaflet@1.4.0/dist/leaflet.js"
            integrity="sha512-QVftwZFqvtRNi0ZyCtsznlKSWOStnDORoefr1enyq5mVL4tmKB3S/EnC3rRJcxCPavG10IcrVGSmPh6Qw5lwrg=="
            crossorigin=""></script>
</head>
<body>
<div id="mapid" style="width: 100%; height: 100%; position: absolute"></div>

<!--导入存在geoJSON_WHU_FeatureCollection中的geoJSON数据-->
<script src="src/geoJSON_WHU_FeatureCollection.js" type="text/javascript"></script>

<script>
    var myMap = L.map('mapid').setView([30.538926, 114.354382], 13);
    L.tileLayer('https://api.tiles.mapbox.com/v4/{id}/{z}/{x}/{y}.png?access_token={accessToken}', {
        attribution: 'Map data &copy; <a href="https://www.openstreetmap.org/">OpenStreetMap</a> contributors, <a href="https://creativecommons.org/licenses/by-sa/2.0/">CC-BY-SA</a>, Imagery © <a href="https://www.mapbox.com/">Mapbox</a>',
        maxZoom: 18,
        id: 'mapbox.streets',
        //accessToken是去官网https://account.mapbox.com/access-tokens/申请的默认公共token
        accessToken: 'pk.eyJ1Ijoid2xtcWppeWl6aCIsImEiOiJjanNwZ29zcTUwOXA5NGFveHEwNmNzZWgxIn0.rf8H02a7Z-PSV9qz471Cww'
    }).addTo(myMap);

    //以上照旧。。。。----------------------------------分割线-----------------------------------------------------------
</script>

<script>
    //myOnEachFeature用来给onEachFeature添加点击后出现弹窗的功能;
    //onEachFeature是一个将feature添加到图层时的一个选项,添加到图层时他就会被调用
    //在本例中用来实现弹窗
    function myOnEachFeature(feature, layer) {
        var popupContent = "<p>这里是一个geoJSON数据<br>类型为:" +
            feature.geometry.type + ",我把它设置成leaflet的vector了。<br><br>";
        // does this feature have a property named popupContent?
        if (feature.properties && feature.properties.name) {
            layer.bindPopup(popupContent+feature.properties.name);
        }
    }

    //根据不同的name,选择不同的背景颜色,传给style
    function myStyle(feature){
        switch(feature.properties.name){
            case "文理学部": return {color: "#ff0000"};
            case "医学部":   return {color: "#0000ff"};
            case "工学部":   return {color: "#EEEE00"};
            case "信息学部": return {color: "#8FBC8F"};
            case "宏博公寓": return {color:"#EEC900"};
        }
    }

    //传给filter,看能不能显示在地图上
    //filter:true即可以,false即不可以
    //结果就是,宏博公寓不能显示在地图上
    function show_on_map(feature, layer) {
        return feature.properties.show_on_map;
    }

    //将geoJSON数据添加到mymap图层之中
    L.geoJSON(geoJSON_WHU_FeatureCollection, {
        style :myStyle,
        onEachFeature: myOnEachFeature,
        filter :show_on_map
    }).addTo(myMap);

</script>
</body>
</html>

其中引入的 geoJSON_WHU_FeatureCollection.js 文件如下

//武汉大学四个学部 + 宏博公寓 的geoJSON数据,type是FeatureCollection,
// 去 http://geojson.io 上自己画的
var geoJSON_WHU_FeatureCollection={
    "type": "FeatureCollection",
    "features": [
        {
            "type": "Feature",
            "properties": {
                "name": "文理学部",
                "show_on_map":true
            },
            "geometry": {
                "type": "Polygon",
                "coordinates": [
                    [
                        [
                            114.35205459594727,
                            30.535502985381292
                        ],
                        [
                            114.3596076965332,
                            30.53254585170109
                        ],
                        [
                            114.36973571777344,
                            30.53084545907189
                        ],
                        [
                            114.37076568603516,
                            30.532693710523137
                        ],
                        [
                            114.37179565429688,
                            30.535133348594492
                        ],
                        [
                            114.37179565429688,
                            30.53735114821524
                        ],
                        [
                            114.37076568603516,
                            30.537794702062474
                        ],
                        [
                            114.36904907226562,
                            30.539051426962313
                        ],
                        [
                            114.36698913574219,
                            30.539273200256535
                        ],
                        [
                            114.36475753784178,
                            30.539273200256535
                        ],
                        [
                            114.36201095581055,
                            30.538977502418366
                        ],
                        [
                            114.3617534637451,
                            30.540160288369066
                        ],
                        [
                            114.36012268066405,
                            30.540234212012663
                        ],
                        [
                            114.3570327758789,
                            30.54030813560003
                        ],
                        [
                            114.35480117797852,
                            30.538829653161645
                        ],
                        [
                            114.35342788696289,
                            30.536168328052764
                        ],
                        [
                            114.35205459594727,
                            30.535502985381292
                        ]
                    ]
                ]
            }
        },
        {
            "type": "Feature",
            "properties": {
                "name": "工学部",
                "show_on_map":true
            },
            "geometry": {
                "type": "Polygon",
                "coordinates": [
                    [
                        [
                            114.35480117797852,
                            30.538829653161645
                        ],
                        [
                            114.35686111450194,
                            30.54045598260588
                        ],
                        [
                            114.3618392944336,
                            30.54030813560003
                        ],
                        [
                            114.36201095581055,
                            30.53912535144998
                        ],
                        [
                            114.3651008605957,
                            30.539421048838012
                        ],
                        [
                            114.36819076538086,
                            30.53912535144998
                        ],
                        [
                            114.37196731567381,
                            30.537498999722725
                        ],
                        [
                            114.37050819396973,
                            30.539568897194382
                        ],
                        [
                            114.36896324157715,
                            30.541047368378486
                        ],
                        [
                            114.36767578124999,
                            30.54459560738242
                        ],
                        [
                            114.36441421508788,
                            30.546147921174956
                        ],
                        [
                            114.35995101928711,
                            30.54829155180099
                        ],
                        [
                            114.35771942138672,
                            30.54740453797207
                        ],
                        [
                            114.3523120880127,
                            30.547774128052346
                        ],
                        [
                            114.34819221496582,
                            30.547921963690516
                        ],
                        [
                            114.34879302978516,
                            30.54163875054966
                        ],
                        [
                            114.3508529663086,
                            30.537646851005153
                        ],
                        [
                            114.35480117797852,
                            30.538829653161645
                        ]
                    ]
                ]
            }
        },
        {
            "type": "Feature",
            "properties": {
                "name": "信息学部",
                "show_on_map":true
            },
            "geometry": {
                "type": "Polygon",
                "coordinates": [
                    [
                        [
                            114.35205459594727,
                            30.53557691256986
                        ],
                        [
                            114.34982299804688,
                            30.53380264451493
                        ],
                        [
                            114.34793472290038,
                            30.529292900678517
                        ],
                        [
                            114.35660362243652,
                            30.526335577959657
                        ],
                        [
                            114.35952186584473,
                            30.53254585170109
                        ],
                        [
                            114.35205459594727,
                            30.53557691256986
                        ]
                    ]
                ]
            }
        },
        {
            "type": "Feature",
            "properties": {
                "name": "医学部",
                "show_on_map":true
            },
            "geometry": {
                "type": "Polygon",
                "coordinates": [
                    [
                        [
                            114.35117483139038,
                            30.55908290420726
                        ],
                        [
                            114.34426546096802,
                            30.558159034014334
                        ],
                        [
                            114.3427848815918,
                            30.555904753831072
                        ],
                        [
                            114.34364318847656,
                            30.55535041461725
                        ],
                        [
                            114.34576749801636,
                            30.55492541907578
                        ],
                        [
                            114.34958696365355,
                            30.55429716138814
                        ],
                        [
                            114.3518829345703,
                            30.55411237894137
                        ],
                        [
                            114.35286998748778,
                            30.555904753831072
                        ],
                        [
                            114.35117483139038,
                            30.55908290420726
                        ]
                    ]
                ]
            }
        }, {
            "type": "Feature",
            "properties": {
                "name":"宏博公寓",
                "show_on_map":false
            },
            "geometry": {
                "type": "Polygon",
                "coordinates": [
                    [
                        [
                            114.35946822166443,
                            30.525485331018817
                        ],
                        [
                            114.35889959335327,
                            30.52495854385541
                        ],
                        [
                            114.35962915420532,
                            30.524413269923986
                        ],
                        [
                            114.36013340950012,
                            30.525004753369974
                        ],
                        [
                            114.35946822166443,
                            30.525485331018817
                        ]
                    ]
                ]
            }

        }
    ]
};

实际效果:
未点击时
点击信息学部之后

通过geoJSON传值的、交互式的地图

https://leafletjs.com/examples/choropleth/

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>JSON第二香</title>
    <!-- 官网让加的第一个-->
    <link rel="stylesheet" href="https://unpkg.com/leaflet@1.4.0/dist/leaflet.css"
          integrity="sha512-puBpdR0798OZvTTbP4A8Ix/l+A4dHDD0DGqYW6RQ+9jxkRFclaxxQb/SJAWZfWAkuyeQUytO7+7N4QKrDh+drA=="
          crossorigin=""/>
    <!-- 官网让加的第二个-->
    <!-- Make sure you put this AFTER Leaflet's CSS -->
    <script src="https://unpkg.com/leaflet@1.4.0/dist/leaflet.js"
            integrity="sha512-QVftwZFqvtRNi0ZyCtsznlKSWOStnDORoefr1enyq5mVL4tmKB3S/EnC3rRJcxCPavG10IcrVGSmPh6Qw5lwrg=="
            crossorigin=""></script>
    <!--第一个定义右上角的框,第二个定义右下角的框,css存他们的style-->
    <!--padding:多大的延伸,font:字体大小/行间距大小,border-radius:矩形的四个角弯曲的弧度-->
    <style>
    .info { padding: 6px 8px; font: 14px/20px Arial, Helvetica, sans-serif; background: white; background: rgba(255,255,255,0.8); box-shadow: 0 0 15px rgba(0,0,0,0.2); border-radius: 5px; } .info h4 { margin: 0 0 5px; color: #777; }
    .legend { text-align: left; line-height: 18px; color: #555; } .legend i { width: 18px; height: 18px; float: left; margin-right: 8px; opacity: 0.7; }
    </style>
</head>
<body>

<div id="map" style="width: 99%; height: 98%; position: absolute"></div>
<!--导入存在geoJSON_WHU_FeatureCollection中的geoJSON数据-->
<script src="src/geoJSON_WHU_FeatureCollection.js" type="text/javascript"></script>

<script>
    var map = L.map('map').setView([30.538926, 114.354382], 13);
    L.tileLayer('https://api.tiles.mapbox.com/v4/{id}/{z}/{x}/{y}.png?access_token={accessToken}', {
        attribution: 'Map data &copy; <a href="https://www.openstreetmap.org/">OpenStreetMap</a> contributors, <a href="https://creativecommons.org/licenses/by-sa/2.0/">CC-BY-SA</a>, Imagery © <a href="https://www.mapbox.com/">Mapbox</a>',
        maxZoom: 18,
        id: 'mapbox.streets',
        //accessToken是去官网https://account.mapbox.com/access-tokens/申请的默认公共token
        accessToken: 'pk.eyJ1Ijoid2xtcWppeWl6aCIsImEiOiJjanNwZ29zcTUwOXA5NGFveHEwNmNzZWgxIn0.rf8H02a7Z-PSV9qz471Cww'
    }).addTo(map);

    //以上照旧。。。。----------------------------------分割线-----------------------------------------------------------
</script>

<script>
    //右上角的那个框框叫info,这是定义他的语句
    //注意,想和鼠标滑进、滑出、点击有交互的时候,得在相应的函数里update
    var info = L.control();
    //创建info,具体为啥我也不懂
    info.onAdd = function (map) {
        this._div = L.DomUtil.create('div', 'info');
        this.update();
        return this._div;
    };
    //当feature的properties传入时,用来更新右上方的语句
    info.update = function (props) {
        this._div.innerHTML = '<h4>武汉大学分区示意图</h4>' +  (props ?
            '<b>' +'学部名:'+ props.name + '</b></br>'+'这里是'+props.name
            : '没有找到数据');//这里特别容易错,我也不知道为什么。一定小心再小心
    };
    info.addTo(map);


    //定义一个根据properties.name返回颜色值的函数,传给style中的fillColor
    function getColor(partName){
        switch(partName){
            case "文理学部": return "#ff0000";
            case "医学部":   return "#0000ff";
            case "工学部":   return "#EEEE00";
            case "信息学部": return "#8FBC8F";
            case "宏博公寓": return "#EEC900";
        }
    }
    //定义一个设置style的函数,style中的fillColor属性由getColor函数传入
    function myStyle(feature){
        return {
            fillColor: getColor(feature.properties.name),
            weight: 2,
            opacity: 1,
            color: 'white',//图形外面划线的颜色
            dashArray: '3',//图形外面划的线为虚线
            fillOpacity: 0.7
        };
    }

    //设置一个鼠标如果放置在上面,他会做什么的函数。传入onEachFeature中的mouseover
    //这里的函数作用是:鼠标在上面时设置一个加粗的边框,style如下所示
    function mouse_Over_Feature(e) {
        var layer = e.target;
        layer.setStyle({
            weight: 5,
            color: '#666',
            dashArray: '',
            fillOpacity: 0.7
        });
        //如果不是 ie/opera/edge 浏览器,就将修改过的,带粗灰色边框的图层,提到最前面来
        if (!L.Browser.ie && !L.Browser.opera && !L.Browser.edge) {
            layer.bringToFront();
        }
        info.update(layer.feature.properties);
    }
    //设置一个鼠标从上面移开时应该做什么的函数,传入onEachFeature中的mouseout
    //这个函数的作用:鼠标如果移开了,将所有的style回复原样
    function mouse_out_Feature(e) {
        geoJSON_layer.resetStyle(e.target);
        info.update();
    }
    //设置一个鼠标点击某一块时的点击事件函数
    //这个函数的作用:鼠标如果点击该区域,他就让这个区域放大,并且放置到屏幕的最中间...
    function click_Feature(e) {
        map.fitBounds(e.target.getBounds());
    }

    //设置一个onEachFeature函数,接受mouseover/mouseout/click函数传来的操作
    //集大成者,各种对图层的操作都在这了
    function onEachFeature(feature, layer) {
        layer.on({
            mouseover:mouse_Over_Feature,
            mouseout: mouse_out_Feature,
            click: click_Feature
        });
    }

    //用一个变量geoJSON_layer来接geoJSON图层的数据,目的:方便对style还原操作
    var geoJSON_layer = L.geoJson(geoJSON_WHU_FeatureCollection, {
        style: myStyle,
        onEachFeature: onEachFeature
    }).addTo(map);

    //右下角那个框框叫legend,创建它。其实它和右上角的框是一个类型,取名不同,位置不同
    var legend = L.control({position: 'bottomright'});
    //创建该框框(并且不会再改变)
    legend.onAdd = function (map) {
        var div = L.DomUtil.create('div', 'info legend');
        //有五层
        var grades = ['文理学部','工学部','信息学部','医学部','宏博公寓'];
        //lables中的每一个是一个grades加上他对应的颜色,lables是直接输入div框框中的值
        var labels = [];
        for (var i = 0; i < grades.length; i++) {
            //每次获取名称和他对应的颜色,颜色通过getcolor函数获取
            labels.push(
                '<i style="background:'+getColor(grades[i]) + '"></i>' + grades[i]
            );
        }
        div.innerHTML = labels.join('<br>');
        return div;
    };
    legend.addTo(map);

    //官网的例子更好,应该照着官网自由发挥
    /*
    legend.onAdd = function (map) {

        var div = L.DomUtil.create('div', 'info legend'),
            grades = [0, 10, 20, 50, 100, 200, 500, 1000],
            labels = [],
            from, to;

        for (var i = 0; i < grades.length; i++) {
            from = grades[i];
            to = grades[i + 1];

            labels.push(
                '<i style="background:' + getColor(from + 1) + '"></i> ' +
                from + (to ? '&ndash;' + to : '+'));
        }

        div.innerHTML = labels.join('<br>');
        return div;
    };
    */
</script>

</body>
</html>

数据在 src/geoJSON_WHU_FeatureCollection.js 之中,前文已给过;
实现:
在这里插入图片描述
鼠标移动到标色区域的上方,右上角会更新数据

Layer Groups and Layers Control

https://leafletjs.com/examples/layers-control/
主要是对底图的控制(至少在sample中是如此体现)

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>layersControl_my_demo</title>
    <!-- 官网让加的第一个-->
    <link rel="stylesheet" href="https://unpkg.com/leaflet@1.4.0/dist/leaflet.css"
          integrity="sha512-puBpdR0798OZvTTbP4A8Ix/l+A4dHDD0DGqYW6RQ+9jxkRFclaxxQb/SJAWZfWAkuyeQUytO7+7N4QKrDh+drA=="
          crossorigin=""/>
    <!-- 官网让加的第二个-->
    <!-- Make sure you put this AFTER Leaflet's CSS -->
    <script src="https://unpkg.com/leaflet@1.4.0/dist/leaflet.js"
            integrity="sha512-QVftwZFqvtRNi0ZyCtsznlKSWOStnDORoefr1enyq5mVL4tmKB3S/EnC3rRJcxCPavG10IcrVGSmPh6Qw5lwrg=="
            crossorigin=""></script>
    <!--第一个定义右上角的框,第二个定义右下角的框,css存他们的style-->
    <!--padding:多大的延伸,font:字体大小/行间距大小,border-radius:矩形的四个角弯曲的弧度-->
    <style>
        .info { padding: 6px 8px; font: 14px/20px Arial, Helvetica, sans-serif; background: white; background: rgba(255,255,255,0.8); box-shadow: 0 0 15px rgba(0,0,0,0.2); border-radius: 5px; } .info h4 { margin: 0 0 5px; color: #777; }
        .legend { text-align: left; line-height: 18px; color: #555; } .legend i { width: 18px; height: 18px; float: left; margin-right: 8px; opacity: 0.7; }
    </style>
</head>
<body>

<div id="map" style="width: 99%; height: 98%; position: absolute"></div>
<!--导入存在geoJSON_WHU_FeatureCollection中的geoJSON数据-->
<script src="src/geoJSON_WHU_FeatureCollection.js" type="text/javascript"></script>

<script>
    //先添加地图的一段被我删了,在最后面再添加地图
</script>

<script>

    //右上角的那个框框叫info,这是定义他的语句
    //注意,想和鼠标滑进、滑出、点击有交互的时候,得在相应的函数里update
    var info = L.control({position:'topleft'});
    //创建info,具体为啥我也不懂
    info.onAdd = function (map) {
        this._div = L.DomUtil.create('div', 'info');
        this.update();
        return this._div;
    };
    //当feature的properties传入时,用来更新右上方的语句
    info.update = function (props) {
        this._div.innerHTML = '<h4>武汉大学分区示意图</h4>' +  (props ?
            '<b>' +'学部名:'+ props.name + '</b></br>'+'这里是'+props.name
            : '没有找到数据');//这里特别容易错,我也不知道为什么。一定小心再小心
    };
    //info.addTo(map);

    //定义一个根据properties.name返回颜色值的函数,传给style中的fillColor
    function getColor(partName){
        switch(partName){
            case "文理学部": return "#ff0000";
            case "医学部":   return "#0000ff";
            case "工学部":   return "#EEEE00";
            case "信息学部": return "#8FBC8F";
            case "宏博公寓": return "#EEC900";
        }
    }
    //定义一个设置style的函数,style中的fillColor属性由getColor函数传入
    function myStyle(feature){
        return {
            fillColor: getColor(feature.properties.name),
            weight: 2,
            opacity: 1,
            color: 'white',//图形外面划线的颜色
            dashArray: '3',//图形外面划的线为虚线
            fillOpacity: 0.7
        };
    }

    //设置一个鼠标如果放置在上面,他会做什么的函数。传入onEachFeature中的mouseover
    //这里的函数作用是:鼠标在上面时设置一个加粗的边框,style如下所示
    function mouse_Over_Feature(e) {
        var layer = e.target;
        layer.setStyle({
            weight: 5,
            color: '#666',
            dashArray: '',
            fillOpacity: 0.7
        });
        //如果不是 ie/opera/edge 浏览器,就将修改过的,带粗灰色边框的图层,提到最前面来
        if (!L.Browser.ie && !L.Browser.opera && !L.Browser.edge) {
            layer.bringToFront();
        }
        info.update(layer.feature.properties);
    }
    //设置一个鼠标从上面移开时应该做什么的函数,传入onEachFeature中的mouseout
    //这个函数的作用:鼠标如果移开了,将所有的style回复原样
    function mouse_out_Feature(e) {
        geoJSON_layer.resetStyle(e.target);
        info.update();
    }
    //设置一个鼠标点击某一块时的点击事件函数
    //这个函数的作用:鼠标如果点击该区域,他就让这个区域放大,并且放置到屏幕的最中间...
    function click_Feature(e) {
        map.fitBounds(e.target.getBounds());
    }

    //设置一个onEachFeature函数,接受mouseover/mouseout/click函数传来的操作
    //集大成者,各种对图层的操作都在这了
    function onEachFeature(feature, layer) {
        layer.on({
            mouseover:mouse_Over_Feature,
            mouseout: mouse_out_Feature,
            click: click_Feature
        });
    }

    //用一个变量geoJSON_layer来接geoJSON图层的数据,目的:方便对style还原操作
    var geoJSON_layer = L.geoJson(geoJSON_WHU_FeatureCollection, {
        style: myStyle,
        onEachFeature: onEachFeature
    });
        //.addTo(cities);

    //创建一个层的聚类,将对geoJSON图层的数据放入layerGroup中,待会儿放在所有图层的上方,一直能显示
    var layer_group = L.layerGroup();
    geoJSON_layer.addTo(layer_group);

    //右下角那个框框叫legend,用来显示颜色图例,创建它。其实它和右上角的框是一个类型,取名不同,位置不同
    var legend = L.control({position: 'bottomright'});
    //创建该框框(并且不会再改变)
    legend.onAdd = function (map) {
        var div = L.DomUtil.create('div', 'info legend');
        //有五层
        var grades = ['文理学部','工学部','信息学部','医学部','宏博公寓'];
        //lables中的每一个是一个grades加上他对应的颜色,lables是直接输入div框框中的值
        var labels = [];
        for (var i = 0; i < grades.length; i++) {
            //每次获取名称和他对应的颜色,颜色通过getcolor函数获取
            labels.push(
                '<i style="background:'+getColor(grades[i]) + '"></i>' + grades[i]
            );
        }
        div.innerHTML = labels.join('<br>');
        return div;
    };

    //添加街道图的语句
    var streets = L.tileLayer('https://api.tiles.mapbox.com/v4/{id}/{z}/{x}/{y}.png?access_token={accessToken}', {
        attribution: 'Map data &copy; <a href="https://www.openstreetmap.org/">OpenStreetMap</a> contributors, <a href="https://creativecommons.org/licenses/by-sa/2.0/">CC-BY-SA</a>, Imagery © <a href="https://www.mapbox.com/">Mapbox</a>',
        maxZoom: 18,
        id: 'mapbox.streets',
        //accessToken是去官网https://account.mapbox.com/access-tokens/申请的默认公共token
        accessToken: 'pk.eyJ1Ijoid2xtcWppeWl6aCIsImEiOiJjanNwZ29zcTUwOXA5NGFveHEwNmNzZWgxIn0.rf8H02a7Z-PSV9qz471Cww'
    });
    //添加卫星图的语句
    var satellite = L.tileLayer('https://api.tiles.mapbox.com/v4/{id}/{z}/{x}/{y}.png?access_token={accessToken}', {
        attribution: 'Map data &copy; <a href="https://www.openstreetmap.org/">OpenStreetMap</a> contributors, <a href="https://creativecommons.org/licenses/by-sa/2.0/">CC-BY-SA</a>, Imagery © <a href="https://www.mapbox.com/">Mapbox</a>',
        maxZoom: 18,
        id: 'mapbox.satellite',
        //accessToken是去官网https://account.mapbox.com/access-tokens/申请的默认公共token
        accessToken: 'pk.eyJ1Ijoid2xtcWppeWl6aCIsImEiOiJjanNwZ29zcTUwOXA5NGFveHEwNmNzZWgxIn0.rf8H02a7Z-PSV9qz471Cww'
    });
    //streets在下,表示geoJSON的layer_group在上
    var map = L.map('map', {
        layers: [streets, layer_group],
        zoomControl:false //显示缩放的控件没有了
    }).setView([30.538926, 114.354382], 13);

    //你想右上角的底图按钮有几个底图,你就在baseLayers中间设置几个
    var baseLayers = {
        "街道图": streets,
        "<span style='color: black'>卫星图</span>": satellite
    };
    //一定要显示的界面
    var overlays = {
        "显示界面": layer_group
    };
    //将系统定义的层选择控件添加入地图,大功告成
    L.control.layers(baseLayers, overlays).addTo(map);

    //div类型的info和legend终究是只能加在地图中的
    info.addTo(map);
    legend.addTo(map);

    //官网的例子更好,应该照着官网自由发挥
    /*
    legend.onAdd = function (map) {

        var div = L.DomUtil.create('div', 'info legend'),
            grades = [0, 10, 20, 50, 100, 200, 500, 1000],
            labels = [],
            from, to;

        for (var i = 0; i < grades.length; i++) {
            from = grades[i];
            to = grades[i + 1];

            labels.push(
                '<i style="background:' + getColor(from + 1) + '"></i> ' +
                from + (to ? '&ndash;' + to : '+'));
        }

        div.innerHTML = labels.join('<br>');
        return div;
    };
    */
</script>

</body>
</html>

数据基于geoJSON_WHU_FeatureCollection.js,前文已给出。
达成效果:
在这里插入图片描述
右上角的负责切换,各种切换

 

网页上播放图片和视频

https://leafletjs.com/examples/video-overlay/
官网上是插入视频(但我觉得插入视频效果不好)

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>IMG_Add_demo</title>
    <!-- 官网让加的第一个-->
    <link rel="stylesheet" href="https://unpkg.com/leaflet@1.4.0/dist/leaflet.css"
          integrity="sha512-puBpdR0798OZvTTbP4A8Ix/l+A4dHDD0DGqYW6RQ+9jxkRFclaxxQb/SJAWZfWAkuyeQUytO7+7N4QKrDh+drA=="
          crossorigin=""/>
    <!-- 官网让加的第二个-->
    <!-- Make sure you put this AFTER Leaflet's CSS -->
    <script src="https://unpkg.com/leaflet@1.4.0/dist/leaflet.js"
            integrity="sha512-QVftwZFqvtRNi0ZyCtsznlKSWOStnDORoefr1enyq5mVL4tmKB3S/EnC3rRJcxCPavG10IcrVGSmPh6Qw5lwrg=="
            crossorigin=""></script>
    <!--第一个定义右上角的框,第二个定义右下角的框,css存他们的style-->
    <!--padding:多大的延伸,font:字体大小/行间距大小,border-radius:矩形的四个角弯曲的弧度-->
    <style>
        .info { padding: 6px 8px; font: 14px/20px Arial, Helvetica, sans-serif; background: white; background: rgba(255,255,255,0.8); box-shadow: 0 0 15px rgba(0,0,0,0.2); border-radius: 5px; } .info h4 { margin: 0 0 5px; color: #777; }
        .legend { text-align: left; line-height: 18px; color: #555; } .legend i { width: 18px; height: 18px; float: left; margin-right: 8px; opacity: 0.7; }
    </style>
</head>
<body>

<div id="map" style="width: 99%; height: 98%; position: absolute"></div>
<!--导入存在geoJSON_WHU_FeatureCollection中的geoJSON数据-->
<script src="src/geoJSON_WHU_FeatureCollection.js" type="text/javascript"></script>

<script>
    //先添加地图的一段被我删了,在最后面再添加地图
</script>

<script>

    //右上角的那个框框叫info,这是定义他的语句
    //注意,想和鼠标滑进、滑出、点击有交互的时候,得在相应的函数里update
    var info = L.control({position:'topleft'});
    //创建info,具体为啥我也不懂
    info.onAdd = function (map) {
        this._div = L.DomUtil.create('div', 'info');
        this.update();
        return this._div;
    };
    //当feature的properties传入时,用来更新右上方的语句
    info.update = function (props) {
        this._div.innerHTML = '<h4>武汉大学分区示意图</h4>' +  (props ?
            '<b>' +'学部名:'+ props.name + '</b></br>'+'这里是'+props.name
            : '没有找到数据');//这里特别容易错,我也不知道为什么。一定小心再小心
    };
    //info.addTo(map);

    //定义一个根据properties.name返回颜色值的函数,传给style中的fillColor
    function getColor(partName){
        switch(partName){
            case "文理学部": return "#ff0000";
            case "医学部":   return "#0000ff";
            case "工学部":   return "#EEEE00";
            case "信息学部": return "#8FBC8F";
            case "宏博公寓": return "#EEC900";
        }
    }
    //定义一个设置style的函数,style中的fillColor属性由getColor函数传入
    function myStyle(feature){
        return {
            fillColor: getColor(feature.properties.name),
            weight: 2,
            opacity: 1,
            color: 'white',//图形外面划线的颜色
            dashArray: '3',//图形外面划的线为虚线
            fillOpacity: 0.7
        };
    }

    //设置一个鼠标如果放置在上面,他会做什么的函数。传入onEachFeature中的mouseover
    //这里的函数作用是:鼠标在上面时设置一个加粗的边框,style如下所示
    function mouse_Over_Feature(e) {
        var layer = e.target;
        layer.setStyle({
            weight: 5,
            color: '#666',
            dashArray: '',
            fillOpacity: 0.7
        });
        //如果不是 ie/opera/edge 浏览器,就将修改过的,带粗灰色边框的图层,提到最前面来
        if (!L.Browser.ie && !L.Browser.opera && !L.Browser.edge) {
            layer.bringToFront();
        }
        info.update(layer.feature.properties);
    }
    //设置一个鼠标从上面移开时应该做什么的函数,传入onEachFeature中的mouseout
    //这个函数的作用:鼠标如果移开了,将所有的style回复原样
    function mouse_out_Feature(e) {
        geoJSON_layer.resetStyle(e.target);
        info.update();
    }
    //设置一个鼠标点击某一块时的点击事件函数
    //这个函数的作用:鼠标如果点击该区域,他就让这个区域放大,并且放置到屏幕的最中间...
    function click_Feature(e) {
        map.fitBounds(e.target.getBounds());
    }

    //设置一个onEachFeature函数,接受mouseover/mouseout/click函数传来的操作
    //集大成者,各种对图层的操作都在这了
    function onEachFeature(feature, layer) {
        layer.on({
            mouseover:mouse_Over_Feature,
            mouseout: mouse_out_Feature,
            click: click_Feature
        });
    }

    //用一个变量geoJSON_layer来接geoJSON图层的数据,目的:方便对style还原操作
    var geoJSON_layer = L.geoJson(geoJSON_WHU_FeatureCollection, {
        style: myStyle,
        onEachFeature: onEachFeature
    });
    //.addTo(cities);

    //创建一个层的聚类,将对geoJSON图层的数据放入layerGroup中,待会儿放在所有图层的上方,一直能显示
    var layer_group = L.layerGroup();
    geoJSON_layer.addTo(layer_group);

    //右下角那个框框叫legend,用来显示颜色图例,创建它。其实它和右上角的框是一个类型,取名不同,位置不同
    var legend = L.control({position: 'bottomright'});
    //创建该框框(并且不会再改变)
    legend.onAdd = function (map) {
        var div = L.DomUtil.create('div', 'info legend');
        //有五层
        var grades = ['文理学部','工学部','信息学部','医学部','宏博公寓'];
        //lables中的每一个是一个grades加上他对应的颜色,lables是直接输入div框框中的值
        var labels = [];
        for (var i = 0; i < grades.length; i++) {
            //每次获取名称和他对应的颜色,颜色通过getcolor函数获取
            labels.push(
                '<i style="background:'+getColor(grades[i]) + '"></i>' + grades[i]
            );
        }
        div.innerHTML = labels.join('<br>');
        return div;
    };

    //添加图片的部分,bounds是latlng显示的坐标
    var imageUrl = 'src/part_Area_WHU_Img.png',
        imageBounds = [[30.566556, 114.268905], [30.512771, 114.32817]];
    var image_layer=L.imageOverlay(imageUrl, imageBounds,{opacity: 0.8});//.addTo(map);
    var layer_group_2 = L.layerGroup();//我创立了一个新的layer_group_2,一个layer的组
    image_layer.addTo(layer_group_2);//将img层 加进去,方便在下面开关/显示

    //添加街道图的语句
    var streets = L.tileLayer('https://api.tiles.mapbox.com/v4/{id}/{z}/{x}/{y}.png?access_token={accessToken}', {
        attribution: 'Map data &copy; <a href="https://www.openstreetmap.org/">OpenStreetMap</a> contributors, <a href="https://creativecommons.org/licenses/by-sa/2.0/">CC-BY-SA</a>, Imagery © <a href="https://www.mapbox.com/">Mapbox</a>',
        maxZoom: 18,
        id: 'mapbox.streets',
        //accessToken是去官网https://account.mapbox.com/access-tokens/申请的默认公共token
        accessToken: 'pk.eyJ1Ijoid2xtcWppeWl6aCIsImEiOiJjanNwZ29zcTUwOXA5NGFveHEwNmNzZWgxIn0.rf8H02a7Z-PSV9qz471Cww'
    });
    //添加卫星图的语句
    var satellite = L.tileLayer('https://api.tiles.mapbox.com/v4/{id}/{z}/{x}/{y}.png?access_token={accessToken}', {
        attribution: 'Map data &copy; <a href="https://www.openstreetmap.org/">OpenStreetMap</a> contributors, <a href="https://creativecommons.org/licenses/by-sa/2.0/">CC-BY-SA</a>, Imagery © <a href="https://www.mapbox.com/">Mapbox</a>',
        maxZoom: 18,
        id: 'mapbox.satellite',
        //accessToken是去官网https://account.mapbox.com/access-tokens/申请的默认公共token
        accessToken: 'pk.eyJ1Ijoid2xtcWppeWl6aCIsImEiOiJjanNwZ29zcTUwOXA5NGFveHEwNmNzZWgxIn0.rf8H02a7Z-PSV9qz471Cww'
    });
    //streets在下,表示geoJSON的layer_group在上
    var map = L.map('map', {
        layers: [streets, layer_group/*,layer_group_2*/],
        zoomControl:false //显示缩放的控件没有了
    }).setView([30.538926, 114.354382], 13);

    //你想右上角的底图按钮有几个底图,你就在baseLayers中间设置几个
    var baseLayers = {
        "街道图": streets,
        "<span style='color: black'>卫星图</span>": satellite
    };
    //一定要显示的界面
    var overlays = {
        "显示界面": layer_group,
          "IMG":  layer_group_2 //一组layer绑定在一个Layergroup中,变成一个可以开关的按钮
    };
    //将系统定义的层选择控件添加入地图,大功告成
    L.control.layers(baseLayers, overlays).addTo(map);

    //div类型的info和legend终究是只能加在地图中的
    info.addTo(map);
    legend.addTo(map);
    //image_layer.addTo(map);

    //官网的例子更好,应该照着官网自由发挥
    /*
    legend.onAdd = function (map) {

        var div = L.DomUtil.create('div', 'info legend'),
            grades = [0, 10, 20, 50, 100, 200, 500, 1000],
            labels = [],
            from, to;

        for (var i = 0; i < grades.length; i++) {
            from = grades[i];
            to = grades[i + 1];

            labels.push(
                '<i style="background:' + getColor(from + 1) + '"></i> ' +
                from + (to ? '&ndash;' + to : '+'));
        }

        div.innerHTML = labels.join('<br>');
        return div;
    };
    */
</script>

</body>
</html>

实际效果如图所示:
屏幕截图
 

  • 8
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
Vue Leaflet 是一种结合了Vue框架和Leaflet库的前端技术,用于展示和操作天地图。天地图是一种具有高清影像和矢量数据的地图服务,提供了丰富的地理信息资源和功能,如地图展示、地图操作、定位导航等。 Vue Leaflet 可以通过调用天地图的API接口,获取并展示天地图的各类地理信息。通过Vue的组件化开发方式,可以方便地在Vue项目中使用这些地理信息,实现自定义的地图功能。例如,在Vue Leaflet 中可以实现地图、标记点、线段、面等地理要素的显示和编辑。 Vue Leaflet 提供了一套方便易用的API和组件,可以轻松地在Vue项目中集成和使用天地图。比如,可以使用Vue Leaflet 提供的地图组件将天地图展示在网页中,可以使用它提供的标记点组件在地图上添加标记,可以使用它提供的工具条组件进行地图的操作和导航等。 使用Vue Leaflet 可以有效地提高开发效率和用户体验。通过其简洁的API和灵活的组件,开发人员可以快速地实现各种地图需求,如显示地图、标记地点、展示线段等。并且,Vue Leaflet 结合了Vue框架的优势,可以更好地组织和管理地图相关的逻辑代码,使开发工作更加方便和高效。 总之,Vue Leaflet 是一种方便、灵活和高效的前端技术,用于展示和操作天地图。它通过结合Vue框架和Leaflet库,提供了一套方便易用的API和组件,帮助开发人员快速实现各种地图需求,提高开发效率和用户体验。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值