新的征程:leaflet官网部分sample修改和实现—–个人笔记
目录
之所以写leaflet样例代码的博客,是因为想记录自己学习过程,提供一个笔记方便回头来看。
为什么要学leaflet?前面学了很久的 ArcGIS API for JS 虽功能齐全样式炫酷,但对于我这样的前端初学者来说十分不友好,并且他对geojson格式的处理也十分僵硬,sample没法改没法学。(不多bb,还是我菜)偶然间发现leaflet对geojson格式的处理很全,有官方sample也有其他人写的样例可以参考,于是做好了重新学习的准备。
纸上得来终觉浅,绝知此事要躬行。前面吃了代码量少的亏,现在多改改才能加深理解。在这片博客里,我把官方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 © <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 © <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图标(存在源文件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 © <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 © <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 ? '–' + 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 © <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 © <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 ? '–' + 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 © <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 © <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 ? '–' + to : '+'));
}
div.innerHTML = labels.join('<br>');
return div;
};
*/
</script>
</body>
</html>
实际效果如图所示:
!!!
转载自:https://blog.csdn.net/qq_35941161/article/details/88054064