戴尬猴,我是德育处主任
本文介绍如何使用 OpenLayers.js
(后面简称 ol
)。ol
是一个开源 JavaScript
库,可用于在Web页面上创建交互式地图。 ol
能帮助我们在浏览器轻松地使用地图功能,例如地图缩放、地图拖动、地图标记和地图交互等。
本文适合想有JS基础,又想了解 ol
的工友。
⚡️ OpenLayers官网
ol
使得在任何网页中放置动态地图变得很容易。它可以显示从任何来源加载的地图块、矢量数据和标记。OpenLayers 的开发是为了进一步利用各种地理信息。它是完全免费的,开放源代码 JavaScript,根据包含2个子句的 BSD 许可证(也称为 FreeBSD)发布。
上面这段话来自 ol
官网的简介。
简单来说,ol
能显示和编辑地图。如果你不想用百度、高德、腾讯等地图,如果你需要高度定制地图,那可以试试 ol
。
在某些特定情况(比如内网)要用到地图编辑功能,也可以使用 ol
。
本文用到的
ol
版本是7.3.0
如果是用脚手架创建的项目,大概率会用 npm
的方式将 ol
安装到项目里。
不管是 npm
还是 cdn
的方式,都需要引入 ol
的 css
和 js
。
本文为了方便,我都会用 cdn
的方式讲解。
安装命令
npm i ol
使用方法
```html
```
上面的代码看不懂没关系,后面会讲到的。
```html rel="stylesheet" href="https://cdn.jsdelivr.net/npm/[email protected]/ol.css">
```
根据前面提到的流程创建出一个地图。
ol.Map()
是地图的容器,它返回一个 ol
地图对象。它可以配置各种图层、加载各种控件。
上面的例子中,ol.Map()
中有3个核心要素:
target
:绑定地图容器的属性,传入容器的 id
即可。layers
:底图图层。ol
支持多图层配置,所以 layers
的值是一个数组。view
:地图视图。可以配置地图的缩放、投影坐标系、中心点、旋转角度等配置项。视图指的是 ol.View
这个类,这是一个很重要的类,它拥有设置地图的中心点、缩放级别、旋转角度等功能。
ol.View
也是我认为初学者比较容易掌握的一个知识点,所以先讲这个。
我们知道在现实世界中使用经纬度可以定义一个位置。
在 ol
中,支持多种定义位置的格式,这些格式都叫投影坐标系。
ol
默认使用的是 EPSG:3857
。如果你习惯了百度地图,比如你使用 百度地图拾取坐标系统 获得的坐标点,想放在 ol
中能对应得上,那就需要配置投影坐标系了。
在 ol
中配置投影坐标系,需要在 ol.View
类里配置,配置项叫做 projection
。
如果你要配置成百度地图的坐标系,可以将 projection
设置为 'EPSG:4326'
```js // 省略部分代码
const map = new ol.Map({ target: 'map', layers: [ new ol.layer.Tile({ source: new ol.source.OSM() }) ], view: new ol.View({ center: [113.267252, 23.137949], // 设置视图中心点 projection: 'EPSG:4326', // 配置投影坐标系 zoom: 11 }) }) ```
在这个例子中,113.267252, 23.137949
这个坐标点是在 百度地图拾取坐标系统 搜“广州”获取到的。
在前面的例子中我们已经知道,ol.View
里可以设置 center
,这就是设置中心点的属性。
js // 省略部分代码 const map = new ol.Map({ target: 'map', layers: [ new ol.layer.Tile({ source: new ol.source.OSM() }) ], view: new ol.View({ center: [113.267252, 23.137949], // 设置视图中心点 projection: 'EPSG:4326', // 配置投影坐标系 zoom: 11 }) })
中心点是打开地图时画布的中心坐标。
同一个坐标在不同投影坐标系所呈现出来的位置是不一样的。
每种底图都有一定程度的缩放级别,这要看你所使用的底图支持多大的缩放级别。
在 ol
中,使用 zoom
可以配置默认的缩放级别,前面的例子中已经演示过了。
前一个例子的缩放级别是 11
,这次我使用 20
来看看效果。
js // 省略部分代码 const map = new ol.Map({ target: 'map', layers: [ new ol.layer.Tile({ source: new ol.source.OSM() }) ], view: new ol.View({ center: [113.267252, 23.137949], projection: 'EPSG:4326', zoom: 20 // 缩放级别 }) })
明显大了很多。
在地图上使用鼠标滚轮上下滚动时,地图层级会缩放。
默认情况下 ol
是不限定缩放级别的,最小缩放级别就是当前底图的最小级别,最大也同理。
如果想要设置最大和最小的缩放级别,可以使用 maxZoom
和 minZoom
进行设置。
js // 省略部分代码 const map = new ol.Map({ target: 'map', layers: [ new ol.layer.Tile({ source: new ol.source.OSM() }) ], view: new ol.View({ center: [113.267252, 23.137949], projection: 'EPSG:4326', zoom: 12, // 缩放级别 minZoom: 10, // 设置最小缩放级别 maxZoom: 14, // 设置最大缩放级别 }) })
我在其他 canvas
类的文章也有讲过,为了方便开发者观察,旋转的公式可以写成这样:
Math.PI / 180 * 旋转角度
比如要旋转 45度,可以这样写:Math.PI / 180 * 45
。
在 ol
中要旋转地图的话,可以配置 rotation
属性。
js // 省略部分代码 const map = new ol.Map({ target: 'map', layers: [ new ol.layer.Tile({ source: new ol.source.OSM() }) ], view: new ol.View({ center: [113.267252, 23.137949], projection: 'EPSG:4326', zoom: 12, // 缩放级别 rotation: Math.PI / 180 * 45, // 旋转地图45度 }) })
好了,简单的用法就大概讲这么多(赶进度)。
以后再单独开篇讲某些特殊属性配置。
图层模块也是 ol
一个非常重要的模块。图层模块为我们提供了在地图上展示和处理各种地理数据的能力。无论是矢量数据、栅格数据还是其他地理信息,ol
的图层模块都能帮助我们轻松加载、显示和操作这些数据。
在 ol
中,图层是通过 layers
来配置的。
这里所说的地图数据是图源的意思,比如百度地图、必应地图等。
在 ol
中,一般使用瓦片地图的图片作为底图。
我们可以通过 layers
配置图层,细心的工友可能发现了,layers
的值是一个数组,而且这个单词后面是加了 s
的,表示复数,这说明图层是可以存在多个的。有 PhotoShop
经验的工友应该能更轻松理解图层的概念。
ol.layer.Tile
是 ol
中的图层类,用于显示瓦片图提供的地图数据。
所谓的瓦片是将一整块地图切割成一小块一小块那样,可以想象一下瓦片房的房顶。
这么设计的原因是为了加快加载速度。
网页上的地图通常有不同的缩放级别,而且地图的面积也很大,如果一次要加载一整张地图,那加载速度会非常慢,于是就出现了瓦片图的概念。
屏幕的尺寸是有限的,在一定的尺寸内只展示该展示的部分,这样就能提升图片的加载速度。
ol.layer.Tile
里需要使用 source
指定要加载的图源。
在前面的例子中我们已经用过 OSM
底图了。OSM
的全称是 OpenStreetMap
,是 ol
内置的底图。
```js // 省略部分代码
new ol.Map({ target:'map', layers: [ new ol.layer.Tils({ source: new ol.source.OSM() }) ] }) ```
前面用到的 OSM
底图是一种图层的图源,但没用魔法工具的工友使用这种图源可能地图会加载得很慢,或者加载不出来。
如果你自己有部署了瓦片图,可以使用自己的图源。又或者使用其他平台提供的图源,比如必应的底图。
使用必应或者百度等底图,需要在他们的平台申请一个 Key
,以必应为例。
申请必应地图的 Key
可以在该网址里申请:https://www.bingmapsportal.com/Application
申请完就可以使用了。
```js // 省略部分代码
const map = new ol.Map({ target: 'map', layers: [ new ol.layer.Tile({ // 使用必应地图 source: new ol.source.BingMaps({ key: '你的Key', // 这里需要填入你申请到的Key imagerySet: 'Aerial' }) }) ], view: new ol.View({ center: [113.267252, 23.137949], // 设置视图中心点 projection: 'EPSG:4326', // 配置投影坐标系 zoom: 12, // 默认缩放级别 }) }) ```
这段代码的关键点是使用 new ol.source.BingMaps()
加载必应地图。
key
是你在 必应地图 中申请到的,imagerySet
是用来设置瓦片图类型的,你可以设置其他类型试试看,比如 Road
图层有一个 visible
属性可以控制它显示或者隐藏。
visible
默认值是 true
,也就是显示。如果你在初始化图层时将它设置为 false
那么它就会隐藏起来。
```js // 省略部分代码
const map = new ol.Map({ target: 'map', // 图层 layers: [ // 加载瓦片图 new ol.layer.Tile({ source: new ol.source.OSM(), visible: false // 隐藏图层 }) ], view: ... }) ```
除了在初始化的时候隐藏图层外,还可以使用 getVisible()
获取图层当前的 visible
状态,可以使用 setVisible
设置图层的 visible
。
```js // 省略部分代码
const map = new ol.Map({ target: 'map', // 图层 layers: [ // 加载瓦片图 new ol.layer.Tile({ // 必应图源 source: new ol.source.BingMaps({ key: '你的Key', imagerySet: 'Aerial' }) }) ], view: new ol.View({ center: [113.267252, 23.137949], // 设置视图中心点 projection: 'EPSG:4326', // 配置投影坐标系 zoom: 12, // 默认缩放级别 }) })
// 显示或隐藏图层 function toggleLayer() { let layers = map.getLayers() // 获取图层组 let layer = layers.item(0) // 因为只有一个图层,所以直接 item(0) 即可拿到 let visible = layer.getVisible() // 获取图层当前显示状态 layer.setVisible(!visible) // 设置图层显示状态 } ```
这段代码需要注意的是,我们当前只有一个图层,所以可以直接使用 map.getLayers().item(0)
获取,如果你的项目中用到多个图层,需要另外判断一下才行。
要设置图层的不透明度,用到的属性叫 opacity
。它接受 0 ~ 1
的值。
js // 省略部分代码 const map = new ol.Map({ target: 'map', layers: [ new ol.layer.Tile({ source: new ol.source.OSM(), opacity: 0.5 // 设置图层不透明度 }) ], view: ... })
可以使用 getOpacity()
方法获取图层的不透明度,可以使用 setOpacity()
设置图层不透明度。
```html
不透明度
```
在这个例子中,我使用了滑块控件去控制图层不透明度,用 div
标签在页面展示当前图层的不透明度。
可以使用 setSource
设置底图,比如将 OSM
改成必应。
修改底图用到的方法叫 setSource()
。
setSource()
接收一个图源作为参数。
```html
设置为OSM 设置为BingMaps
```
前面用到的都是位图作为底图,相信各位接触过前端的工友都知道位图和矢量图的差别,位图加载速度可能会慢点,而且某些情况可能会失真,而矢量图是不失真的。
我推荐一个矢量地图下载地址:DataV.GeoAtlas
大家可以在这个地址下载矢量图并应用到 ol
里。
加载方式如下
```js // 省略部分代码
const map = new ol.Map({ target: 'map', layers: [ new ol.layer.Vector({ source: new ol.source.Vector({ format: new ol.format.GeoJSON(), url: '../data/geojson.json' }) }) ], view: new ol.View({ center: [0, 0], zoom: 2 }) }) ```
我们加载的是一份 GeoJSON
的数据,GeoJSON
是一种对各种空间数据结构进行编码的格式,可以理解为它就是一份“具有地图规范格式的 JSON
”。
url
属性指向的是这份 JSON
的位置。
ol
自带了一些控件,比如比例尺、全屏等控件。
ol
要添加控件,可以在创建地图时加多一个 controls
属性。
基本所有地图都有比例尺,而尺子也有各种单位,比如度、英尺、海里、公制等。需要什么单位的单位可以自行设置。
ol
要将比例尺调取出来,用的是 ol.control.ScaleLine()
。
首先,要实例化比例尺,然后在创建地图时,将比例尺添加到 controls
属性里。
上图左下角就是比例尺。
```js // 省略部分代码
// 实例化比例尺 const scaleLineControl = new ol.control.ScaleLine() // 比例尺工具
const map = new ol.Map({ target: 'map', layers: [ new ol.layer.Tile({ source: new ol.source.OSM() }) ], view: new ol.View({ center: [0, 0], zoom: 2 }), // 添加控件 controls: ol.control.defaults.defaults().extend([ scaleLineControl ]) }) ```
ol
的比例尺支持的单位:degrees度、imperial英制英尺、us美制英尺、nautical海里、metric公制。
如果不传单位,默认使用 metric
。
你可以在初始化比例尺的时候传入单位:
```js // 省略部分代码
const scaleLineControl = new ol.control.ScaleLine({ units: 'degrees' }) ```
除了初始化时设置比例尺单位之外,还可以使用通过 setUnits()
方法设置
```html 度英制英尺美制英尺海里公制
```
ol
在地图内提供了全屏控件,点击一下就可以进入全屏模式。
全屏控件的名字叫 FullScreen
。
```js // 省略部分代码...
const map = new ol.Map({ target: 'map', layers: [ new ol.layer.Tile({ source: new ol.source.OSM() }) ], view: new ol.View({ center: [0, 0], zoom: 2 }), // 添加控件 controls: ol.control.defaults.defaults().extend([ new ol.control.FullScreen() // 全屏控件 ]) }) ```
鹰眼控件就是左下角出现的小地图,它也叫缩略图或者鸟瞰图。
鹰眼控件在 ol
里的名字叫 OverviewMap
。
既然它是小地图,那理所当然的就可以配一个底图给它。
```js // 省略部分代码
// 鹰眼控件 let overviewMapControl = new ol.control.OverviewMap({ className: 'ol-overviewmap ol-custom-overviewmap', layers: [ new ol.layer.Tile({ // 使用必应地图 source: new ol.source.BingMaps({ key: 'AiZrfxUNMRpOOlCpcMkBPxMUSKOEzqGeJTcVKUrXBsUdQDXutUBFN3-GnMNSlso-', imagerySet: 'Aerial' }) })
], collapsed: false })
const map = new ol.Map({ target: 'map', layers: [ new ol.layer.Tile({ source: new ol.source.OSM() // 基础地图使用 OSM }) ], view: new ol.View({ projection: "EPSG:4326", center: [114.064839, 22.548857], zoom: 6 }), // 添加控件 controls: ol.control.defaults.defaults().extend([ overviewMapControl ]) }) ```
从这个例子可以看出,默认的大地图使用了 OSM
,小地图用了必应地图。
鹰眼控件的 collapsed
属性设置为 false
,意味着小地图默认是打开的。
导览控件是一个缩放到指定范围的按钮。
导览控件在 ol
中叫 ZoomToExtent
,它接收一个对象参数,通过 extent
属性指定了一个范围坐标。这个范围坐标定义了地图应该缩放到的目标范围。
js // 省略部分代码 const map = new ol.Map({ target: 'map', layers: [ new ol.layer.Tile({ source: new ol.source.OSM() }) ], view: new ol.View({ center: [0, 0], zoom: 2 }), // 添加控件 controls: ol.control.defaults.defaults().extend([ new ol.control.ZoomToExtent({ // 定义要展示区域的4个角的坐标 extent: [ 813079.7791264898, 5929220.284081122, 848966.9639063801, 5936863.986909639 ] }) ]) })
ol
除了使用鼠标滚轮缩放地图外,还提供了一个滑块控件给用户缩放地图。
这个控件的名字叫 ZoomSlider
```js // 省略部分代码
const map = new ol.Map({ target: 'map', layers: [ new ol.layer.Tile({ source: new ol.source.OSM() }) ], view: new ol.View({ projection: 'EPSG:4326', center: [114.064839, 22.548857], zoom: 2 }), // 添加控件 controls: ol.control.defaults.defaults().extend([ // 缩放滑块控件 new ol.control.ZoomSlider() ]) }) ```
常用的控件先讲到这,其他特殊控件以后还会开文章继续讲\~
以上是 ol
的入门内容,但 ol
的功能远不止本文介绍的这丁点,之后我会在本文的基础上继续介绍 ol
的其他内容\~
⭐ openlayers基础用法
点赞 + 关注 + 收藏 = 学会了