Leaflet 入门

Leaflet 入门

因为在接下来的项目当中会用到 Leaflet 相关内容,所以就打算从头开始系统的学习一下 Leaflet,本文的作用主要是简单的梳理一下在使用 Leaflet 的过程当中遇到的一些问题,主要参考的是 官网 当中提供的一些示例,下面我们就从最为基本的入门知识开始看起

文中所涉及到的所有 Leaflet 示例均可在 leaflet-example 当中找到

什么是 Leaflet

其实简单来说, Leaflet 是一个开放源代码库,通过它我们可以部署简单,交互式,轻量级的 Web 地图,主要有以下三个特点

  • 允许使用诸如 Tile 图层,WMS,标记,弹出窗口,Vector 图层(折线,多边形,圆形等),图像叠加层和 GeoJSON 等图层
  • 可以通过拖动地图,缩放(通过双击或滚轮滚动),使用键盘,使用事件处理以及拖动标记来与 Leaflet 地图进行交互
  • 支持台式机上的 ChromeFirefoxSafari 5+Opera 12+IE 7-11 等浏览器,以及移动设备上的 SafariAndroidChromeFirefox 等浏览器

加载地图

下面我们就来看看如何在网页上加载地图,首先我们需要一个容器以及加载 Leaflet 对应的 JavaScriptCSS 脚本,如下

1
2
3
4
<link rel="stylesheet" href="http://cdn.leafletjs.com/leaflet-0.7.3/leaflet.css">
<script src="https://cdn.leafletjs.com/leaflet-0.7.3/leaflet.js"></script>

<div id="map" style="width: 900px height: 580px"></div>

这一步我们就不过多解释了,接下来我们需要配置地图选项,Leaflet 提供了几个选项,例如类型 ControlInteractionMap StateAnimation 等,我们可以根据这些值来设定我们的自定义地图,首先我们需要创建一个 mapOptions 对象,并设置选项 centerzoom 的值,其中

  • center 表示我们需要传递一个 LatLng 对象,该对象指定我们要在地图上居中的位置,它的值是一个包含指定经纬度的数组
  • zoom 表示我们需要传递一个表示地图缩放级别的整数
1
2
3
4
var mapOptions = {
center: [17.385044, 78.486671],
zoom: 10
}

有了 mapOptions 以后,下面我们就需要建立地图物件,这里我们可以通过实例化 Leaflet 为我们提供的 Map 类来创建 map 对象,在实例化时,我们需要传递两个参数

  • 首先就是我们的地图容器
  • 其次就是我们上面所提到的 mapOptions
1
var map = new L.map('map', mapOptions)

然后我们还需要创建图层对象,我们可以通过实例化 TileLayer 类来加载和显示各种类型的地图(平铺图层),在实例化时我们需要传递一个 URL 模板,它会从服务提供商处请求所需的平铺图层(地图),在这里,我们使用了 openstreetmap

1
var layer = new L.TileLayer('http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png')

当然我们也可以加载各种服务提供商的图层,例如 Open TopoThunder forestHydda,ESRIOpen weatherNASA GIBS 等,我们只需要在创建 TileLayer 时传递各自的 URL 即可,下面是 Openstreetmap 提供的图层的 URL,在使用过程当中可以自行选择

Map Type URL and Output
Mapnik http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png
Black And White http://{s}.tiles.wmflabs.org/bw-mapnik/{z}/{x}/{y}.png
DE http://{s}.tile.openstreetmap.de/tiles/osmde/{z}/{x}/ {y}.png
France http://{s}.tile.openstreetmap.fr/osmfr/{z}/{x}/{y}.png
Hot http://{s}.tile.openstreetmap.fr/hot/{z}/{x}/{y}.png
BZH http://tile.openstreetmap.bzh/br/{z}/{x}/{y}.png

最后一步就是在地图上添加图层,我们可以使用 addlayer() 方法将上一步中创建的图层添加到地图对象,如下所示

1
map.addLayer(layer)

我们将上面所涉及到的内容简单梳理一下,其实 Leaflet 的加载原理很简单,就是通过 new L.TileLayer(url, options) 生成一个图层实例,然后将这个图层添加到地图上面就可以了,汇总代码如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
// 配置地图选项
var mapOptions = {
center: [17.385044, 78.486671],
zoom: 10
}

// 创建地图对象
var map = new L.map('map', mapOptions)

// 创建图层对象
var layer = new L.TileLayer('http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png')

// 在地图上添加图层
map.addLayer(layer)

以上代码在页面上会生成以下输出

标记

下面我们来看看如何在地图上添加标记以及如何自定义,动画化和删除它们,我们先从添加标记开始看起,我们在上面已经介绍了如何加载地图,在此基础之上,我们只需要通过传递表示要标记位置的 latlng 对象来实例化 Marker 类即可,如下所示

1
var marker = new L.Marker([17.385044, 78.486671])

然后使用 Marker 类的 addTo() 方法将在先前步骤中创建的标记对象添加到地图当中即可,简单汇总一下如下所示

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
// 配置地图选项
var mapOptions = {
center: [17.385044, 78.486671],
zoom: 10
}

// 创建地图对象
var map = new L.map('map', mapOptions)

// 创建图层对象
var layer = new L.TileLayer('http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png')

// 在地图上添加图层
map.addLayer(layer)

// 添加标记对象
var marker = L.marker([17.385044, 78.486671])

// 将创建的标记对象添加到地图当中
marker.addTo(map)

效果如下所示

不过光有标记还不行,通常我们会给标记点加上交互事件,比如点击标记后弹出一个提示窗口等,这个也很容易实现,我们只需要使用 bindPopup() 将弹出窗口附加到标记上即可,如下所示

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
// 配置地图选项
var mapOptions = {
center: [17.385044, 78.486671],
zoom: 10
}

// 创建地图对象
var map = new L.map('map', mapOptions)

// 创建图层对象
var layer = new L.TileLayer('http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png')

// 在地图上添加图层
map.addLayer(layer)

// 添加标记对象
var marker = L.marker([17.385044, 78.486671])

// 将弹出窗口附加到标记对象上
marker.bindPopup('Hi Welcome to Tutorialspoint').openPopup()

// 将创建的标记对象添加到地图当中
marker.addTo(map)

效果如下所示

当然,我们在创建标记时,除了 latlang 对象外,我们还可以传递标记选项变量,通过该选项我们可以配置标记的各种属性,例如图标,可拖动,alt 等,详细可以参考官方文档 Marker Options,这里我们只用几个属性来进行测试一下

和之前的 mapOptions 一样,我们可以创建一个 markerOptions 对象,并设置 clickabledraggable

1
2
3
4
5
var markerOptions = {
title: 'MyLocation',
clickable: true,
draggable: true
}

然后稍微调整一下之前实例化 Marker 类的过程,不在单单传入 latlng 对象,而是连同 options 对象一起传入

1
var marker = L.marker([17.385044, 78.486671], markerOptions)

还是老规矩,我们简单的汇总一下,看看效果,如下所示

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
// 配置地图选项
var mapOptions = {
center: [17.385044, 78.486671],
zoom: 10
}

// 创建地图对象
var map = new L.map('map', mapOptions)

// 创建图层对象
var layer = new L.TileLayer('http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png')

// 在地图上添加图层
map.addLayer(layer)

// 创建标记配置
var markerOptions = {
title: 'MyLocation',
clickable: true,
draggable: true
}

// 添加标记对象
var marker = L.marker([17.385044, 78.486671], markerOptions)

// 将弹出窗口附加到标记对象上
marker.bindPopup('Hi Welcome to Tutorialspoint').openPopup()

// 将创建的标记对象添加到地图当中
marker.addTo(map)

效果如下所示,操作后可以发现,现在的标记是可以拖动的,并且当鼠标悬停时会显示 MyLocation 的标识

此外我们还可以单独添加弹出框,只需使用 Leafletpopup 方法即可创建了一个 Popup 实例,并使用 setLatLng 设置 Popup 的位置,然后使用 setContent 设置 Popup 的提示内容,最后使用 addTo 或者 openOn 方法将新建的 Popup 实例添加到地图上就可以了

1
2
3
4
5
var popup = L.popup()
.setLatLng([17.438139, 78.395830])
.setContent('一个 Popup 图层')
// .openOn(map)
.addTo(map)

这里我们需要注意的就是 addToopenOn 方法的区别,简单来说,使用 addTo 方法添加的 Popup 会按照顺序添加,而 openOn 方法则比较霸道,如果之前添加的 Popup 即使已经使用 openPopup 了,但是也会被收起来,然后让 openOn 的弹出层显示出来

下面我们再来看看如何使用自定义图标来定义标记,除了 Leaflet 库提供的默认图标,我们其实还可以添加自己的图标,首先使用 L.icon() 的方式创建一个自定义图标,其中传入 iconOptions 配置参数,如下所示

1
2
3
4
5
6
7
// 自定义 ICON
var iconOptions = {
iconUrl: 'logo.png',
iconSize: [50, 50]
}

var customIcon = L.icon(iconOptions)

接下来再将我们的 customIcon 配置到我们之前创建的的 markerOptions 当中即可

1
2
3
4
5
6
var markerOptions = {
title: 'MyLocation',
clickable: true,
draggable: true,
icon: customIcon
}

简单汇总一下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
// 配置地图选项
var mapOptions = {
center: [17.385044, 78.486671],
zoom: 10
}

// 创建地图对象
var map = new L.map('map', mapOptions)

// 创建图层对象
var layer = new L.TileLayer('http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png')

// 在地图上添加图层
map.addLayer(layer)

// ICON 配置
var iconOptions = {
iconUrl: 'logo.png',
iconSize: [50, 50]
}

// 创建自定义 ICON
var customIcon = L.icon(iconOptions)

// 创建标记配置
var markerOptions = {
title: 'MyLocation',
clickable: true,
draggable: true,
icon: customIcon
}

// 添加标记对象
var marker = L.marker([17.385044, 78.486671], markerOptions)

// 将弹出窗口附加到标记对象上
marker.bindPopup('Hi Welcome to Tutorialspoint').openPopup()

// 将创建的标记对象添加到地图当中
marker.addTo(map)

矢量层

我们在上面介绍了加载地图,以及在地图上面添加标记,但是除了标记以外,我们还可以添加各种形状,例如圆形,多边形,矩形,折线等,所以在本小节当中,我们就来看看如何使用 Google Maps 提供的各种形状,我们就先从折线开始看起

原理其实与添加标记类似,我们首先创建一个 latlangs 变量来保存绘制折线的点,然后使用 L.polyline() 来创建折线,在将我们的 latlangs 变量与一个指定线条的颜色的对象传入,最后在使用对应类当中所提供的的 addTo() 方法将折线添加到地图中即可

1
2
3
4
5
6
7
8
9
10
var latlngs = [
[17.385044, 78.486671],
[16.506174, 80.648015],
[17.000538, 81.804034],
[17.686816, 83.218482]
]

var polyline = L.polyline(latlngs, { color: 'red' })

polyline.addTo(map)

效果是下面这样的

同样的,三角形的实现原理也是一样的,我们直接来看代码

1
2
3
4
5
6
7
8
9
var latlngs = [
[17.385044, 78.486671],
[16.506174, 80.648015],
[17.686816, 83.218482]
]

var polygon = L.polygon(latlngs, { color: 'red' })

polygon.addTo(map)

效果是下面这样的

下面我们再来看看矩形的绘制,代码如下

1
2
3
4
5
6
7
8
9
10
var latlngs = [
[17.342761, 78.552432],
[16.396553, 80.727725]
]

var rectOptions = { color: 'red', weight: 1 }

var rectangle = L.rectangle(latlngs, rectOptions)

rectangle.addTo(map)

效果是下面这样的

最后我们再来看看圆的实现方式,它与上面所介绍到的区别就是需要多传入一个半径的参数,代码如下

1
2
3
4
5
6
7
8
9
10
11
var circleCenter = [17.385044, 78.486671]

var circleOptions = {
color: 'red',
fillColor: '#f03',
fillOpacity: 0
}

var circle = L.circle(circleCenter, 50000, circleOptions)

circle.addTo(map)

效果是下面这样的

另外需要注意的是,使用 L.circle(coordsArr, options) 方法创建的是一个固定半径的圆,它的半径为平面距离,所以会随着地图的缩放,变换大小

如果想创建一个固定半径的圆,也就是像素值固定,不会跟随地图变换大小的圆我们可以使用 L.circleMarker(coordsArr, options) 方法

多段线和多图形

我们在上面介绍了圆形,三角形,矩形,多段线的添加,下面我们再来看看如何添加多个多段线和多个三角形,原理其实是类似的,只是我们创建用来保存绘制点的 latlangs 变量有所不同,先来看看多折线的实现

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
var latlang = [
[
[17.385044, 78.486671],
[16.506174, 80.648015],
[17.686816, 83.218482]
],
[
[13.08268, 80.270718],
[12.971599, 77.594563],
[15.828126, 78.037279]
],
]

var multiPolyLineOptions = { color: 'red' }

var multipolyline = L.multiPolyline(latlang , multiPolyLineOptions)

multipolyline.addTo(map)

最终实现的效果是下面这样的

多个三角形的实现原理类似,我们直接来看代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
var latlang = [
[
[17.385044, 78.486671],
[16.506174, 80.648015],
[17.686816, 83.218482]
],
[
[13.08268, 80.270718],
[12.971599, 77.594563],
[15.828126, 78.037279]
],
]

var multiPolygonOptions = { color: 'red' }

var multipolygon = L.multiPolygon(latlang , multiPolygonOptions)

multipolygon.addTo(map)

效果是下面这样的

基础部分当相关内容我们暂时就介绍到这里,在接下来当章节当中我们会来看看如何将上面介绍到的相关内容组合起来进行使用

参考

# GIS

评论

Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×