开箱即用的openlayer地图效果

本文简介

本文介绍如何使用 OpenLayers.js (后面简称 ol)。ol 是一个开源 JavaScript 库,可用于在Web页面上创建交互式地图。 ol能帮助我们在浏览器轻松地使用地图功能,例如地图缩放、地图拖动、地图标记和地图交互等。

实现效果如图

OpenLayers简介

⚡️ OpenLayers官网

ol 使得在任何网页中放置动态地图变得很容易。它可以显示从任何来源加载的地图块、矢量数据和标记。OpenLayers 的开发是为了进一步利用各种地理信息。它是完全免费的,开放源代码 JavaScript,根据包含2个子句的 BSD 许可证(也称为 FreeBSD)发布。

上面这段话来自 ol 官网的简介。

简单来说,ol 能显示和编辑地图。如果你不想用百度、高德、腾讯等地图,如果你需要高度定制地图,那可以试试 ol

在某些特定情况(比如内网)要用到地图编辑功能,也可以使用 ol

安装 OpenLayers

本文用到的 ol 版本是 7.3.0

如果是用脚手架创建的项目,大概率会用 npm 的方式将 ol 安装到项目里。

不管是 npm 还是 cdn 的方式,都需要引入 olcssjs

本文为了方便,我都会用 cdn 的方式讲解。

npm

安装命令

css 复制代码
css
 体验AI代码助手
 代码解读
复制代码
npm i ol

使用方法

xml 复制代码
html
 体验AI代码助手
 代码解读
复制代码
<style>
  .map-x {
    width: 600px;
    height: 600px;
  }
</style>

<div id="map" class="map-x"></div>

<script>
import 'ol/ol.css'
import { Map, View } from 'ol'
import Tile from 'ol/layer/Tile'
import OSM from 'ol/source/OSM'

new Map({
  target: 'map', // 绑定html元素
  layers: [ // 图层
    new Tile({
      source: new OSM() // 图层数据源(OSM可以在练习时使用,千万别用在真实项目!!!)
    })
  ],
  view: new View({ // 地图视图
    projection: "EPSG:4326", // 坐标系,有EPSG:4326和EPSG:3857
    center: [114.064839, 22.548857], // 深圳坐标
    zoom: 12 // 地图缩放级别(打开页面时默认级别)
  })
})
</script>

上面的代码看不懂没关系,后面会讲到的。

重点声明!!!

在使用 ol 渲染地图时,需要用到一些底图。

本文会提到 OSM 图源,但 OSM 图源的边界可能不是那么精准,在学习时使用该图源没问题,但切勿在真实项目中使用OSM图源!!!切记!切记!

ol.Map() 是地图的容器,它返回一个 ol 地图对象。它可以配置各种图层、加载各种控件。

上面的例子中,ol.Map() 中有3个核心要素:

  • target:绑定地图容器的属性,传入容器的 id 即可。

  • layers:底图图层。ol 支持多图层配置,所以 layers 的值是一个数组。

  • view:地图视图。可以配置地图的缩放、投影坐标系、中心点、旋转角度等配置项。

设置中心点

在前面的例子中我们已经知道,ol.View 里可以设置 center,这就是设置中心点的属性。

php 复制代码
js
 体验AI代码助手
 代码解读
复制代码
// 省略部分代码
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 来看看效果。

php 复制代码
js
 体验AI代码助手
 代码解读
复制代码
// 省略部分代码
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 是不限定缩放级别的,最小缩放级别就是当前底图的最小级别,最大也同理。

如果想要设置最大和最小的缩放级别,可以使用 maxZoomminZoom 进行设置。

php 复制代码
js
 体验AI代码助手
 代码解读
复制代码
// 省略部分代码
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 类的文章也有讲过,为了方便开发者观察,旋转的公式可以写成这样:

javascript 复制代码
javascript
 体验AI代码助手
 代码解读
复制代码
Math.PI / 180 * 旋转角度

比如要旋转 45度,可以这样写:Math.PI / 180 * 45

ol 中要旋转地图的话,可以配置 rotation 属性。

php 复制代码
js
 体验AI代码助手
 代码解读
复制代码
// 省略部分代码
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.Tileol 中的图层类,用于显示瓦片图提供的地图数据。

所谓的瓦片是将一整块地图切割成一小块一小块那样,可以想象一下瓦片房的房顶。

这么设计的原因是为了加快加载速度。

网页上的地图通常有不同的缩放级别,而且地图的面积也很大,如果一次要加载一整张地图,那加载速度会非常慢,于是就出现了瓦片图的概念。

屏幕的尺寸是有限的,在一定的尺寸内只展示该展示的部分,这样就能提升图片的加载速度。

ol.layer.Tile 里需要使用 source 指定要加载的图源。

OSM

在前面的例子中我们已经用过 OSM 底图了。OSM 的全称是 OpenStreetMap ,是 ol 内置的底图。

php 复制代码
js
 体验AI代码助手
 代码解读
复制代码
// 省略部分代码

new ol.Map({
  target:'map',
  layers: [
    new ol.layer.Tils({
      source: new ol.source.OSM()
    })
  ]
})

显示 / 隐藏图层

图层有一个 visible 属性可以控制它显示或者隐藏。

visible 默认值是 true,也就是显示。如果你在初始化图层时将它设置为 false 那么它就会隐藏起来。

php 复制代码
js
 体验AI代码助手
 代码解读
复制代码
// 省略部分代码

const map = new ol.Map({
  target: 'map',
  // 图层
  layers: [
    // 加载瓦片图
    new ol.layer.Tile({
      source: new ol.source.OSM(),
      visible: false // 隐藏图层
    })
  ],
  view: ...
})

除了在初始化的时候隐藏图层外,还可以使用 getVisible() 获取图层当前的 visible 状态,可以使用 setVisible 设置图层的 visible

javascript 复制代码
js
 体验AI代码助手
 代码解读
复制代码
// 省略部分代码

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 的值。

php 复制代码
js
 体验AI代码助手
 代码解读
复制代码
// 省略部分代码
const map = new ol.Map({
  target: 'map',
  layers: [
    new ol.layer.Tile({
      source: new ol.source.OSM(),
      opacity: 0.5 // 设置图层不透明度
    })
  ],
  view: ...
})

可以使用 getOpacity() 方法获取图层的不透明度,可以使用 setOpacity() 设置图层不透明度。

xml 复制代码
html
 体验AI代码助手
 代码解读
复制代码
<style>
  #map {
    width: 400px;
    height: 400px;
  }
</style>

<label for="checkboxEl">不透明度</label>
<!-- 滑块控件,用来设置图层不透明度的值 -->
<input
  id="rangeEl"
  type="range"
  checked="true"
  min="0"
  max="1"
  step="0.01"
  value="0.5"
/>

<div id="opacityValue">不透明度: 0.5</div>

<div id="map"></div>

<script src="../ol/ol.js"></script>
<script>

  const map = new ol.Map({
    target: 'map',
    layers: [
      new ol.layer.Tile({
        source: new ol.source.OSM(),
        opacity: 0.5 // 设置图层不透明度
      })
    ],
    view: new ol.View({
      center: [0, 0],
      zoom: 2
    })
  })

  let rangeEl = document.getElementById('rangeEl')
  rangeEl.addEventListener('change', function() {

    let layers = map.getLayers() // 获取图层组
    let osmLayer = layers.item(0) // 因为只有一个图层,所以直接 item(0) 即可拿到

    osmLayer.setOpacity(parseFloat(this.value)) // 设置图层不透明度

    opacityValue.innerHTML = `不透明度: ${osmLayer.getOpacity()}` // 获取图层不透明度,并展示在页面中
  })
</script>

在这个例子中,我使用了滑块控件去控制图层不透明度,用 div 标签在页面展示当前图层的不透明度。

修改底图

可以使用 setSource 设置底图,比如将 OSM 改成必应。

修改底图用到的方法叫 setSource()

setSource() 接收一个图源作为参数。

xml 复制代码
html
 体验AI代码助手
 代码解读
复制代码
<style>
  #map {
    width: 400px;
    height: 400px;
  }
</style>

<button onclick="switchSource('osm')">设置为OSM</button>
<button onclick="switchSource('bingmap')">设置为BingMaps</button>
<div id="map"></div>

<script src="../ol/ol.js"></script>
<script>
  let osm = new ol.source.OSM()

  let bingmap = new ol.source.BingMaps({
    key: '你的key',
    imagerySet: 'Aerial'
  })


  let layer = new ol.layer.Tile() 

  let map = new ol.Map({
    target: 'map',
    layers: [layer],
    view: new ol.View({
      projection: "EPSG:4326", // 坐标系,有EPSG:4326和EPSG:3857
      center: [114.064839, 22.548857], // 深圳坐标
      zoom: 12
    })
  })

  // 设置图层源
  layer.setSource(osm)

  // 切换图层源
  function switchSource(data) {
    switch(data) {
      case 'osm':
        layer.setSource(osm)
        break
      case 'bingmap':
        layer.setSource(bingmap)
        break
    }
  }
</script>

基础控件

ol 自带了一些控件,比如比例尺、全屏等控件。

ol 要添加控件,可以在创建地图时加多一个 controls 属性。

比例尺

基本所有地图都有比例尺,而尺子也有各种单位,比如度、英尺、海里、公制等。需要什么单位的单位可以自行设置。

ol 要将比例尺调取出来,用的是 ol.control.ScaleLine()

首先,要实例化比例尺,然后在创建地图时,将比例尺添加到 controls 属性里。

上图左下角就是比例尺。

php 复制代码
js
 体验AI代码助手
 代码解读
复制代码
// 省略部分代码

// 实例化比例尺
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

你可以在初始化比例尺的时候传入单位:

php 复制代码
js
 体验AI代码助手
 代码解读
复制代码
// 省略部分代码

const scaleLineControl = new ol.control.ScaleLine({
  units: 'degrees'
})

除了初始化时设置比例尺单位之外,还可以使用通过 setUnits() 方法设置

xml 复制代码
html
 体验AI代码助手
 代码解读
复制代码
<select id="units">
  <option value="degrees">度</option>
  <option value="imperial">英制英尺</option>
  <option value="us">美制英尺</option>
  <option value="nautical">海里</option>
  <option value="metric" selected>公制</option>
</select>

<div id="map"></div>

<script>
  // 比例尺工具
  const scaleLineControl = new ol.control.ScaleLine({
    units: 'degrees'
  })

  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: 12
    }),
    // 添加控件
    controls: ol.control.defaults.defaults().extend([
      scaleLineControl
    ])
  })

  // 获取页面上的单位选择器
  const unitsSelect = document.getElementById('units')

  // 修改比例尺单位的方法
  function onChange() {
    scaleLineControl.setUnits(unitsSelect.value)
  }

  unitsSelect.addEventListener('change', onChange)
</script>

全屏控件

ol 在地图内提供了全屏控件,点击一下就可以进入全屏模式。

全屏控件的名字叫 FullScreen

php 复制代码
js
 体验AI代码助手
 代码解读
复制代码
// 省略部分代码...

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

既然它是小地图,那理所当然的就可以配一个底图给它。

php 复制代码
js
 体验AI代码助手
 代码解读
复制代码
// 省略部分代码

// 鹰眼控件
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 属性指定了一个范围坐标。这个范围坐标定义了地图应该缩放到的目标范围。

php 复制代码
js
 体验AI代码助手
 代码解读
复制代码
// 省略部分代码
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

php 复制代码
js
 体验AI代码助手
 代码解读
复制代码
// 省略部分代码

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()
  ])
})

常用的控件先讲到这吧

喜欢的小伙伴 私信发送源码

相关推荐
姑苏洛言14 分钟前
有趣的 npm 库 · json-server
前端
知否技术18 分钟前
Vue3项目中轻松开发自适应的可视化大屏!附源码!
前端·数据可视化
Hilaku20 分钟前
为什么我坚持用git命令行,而不是GUI工具?
前端·javascript·git
用户adminuser22 分钟前
深入理解 JavaScript 中的闭包及其实际应用
前端
heartmoonq24 分钟前
个人对于sign的理解
前端
ZzMemory24 分钟前
告别移动端适配烦恼!pxToViewport 凭什么取代 lib-flexible?
前端·css·面试
Running_C28 分钟前
从「救命稻草」到「甜蜜的负担」:我对 TypeScript 的爱恨情仇
前端·typescript
狂炫一碗大米饭1 小时前
如何优化vue中的渲染🔒🔑🔓
vue.js
前端搬运侠1 小时前
📝从零到一封装 React 表格:基于 antd Table 实现多条件搜索 + 动态列配置,代码可直接复用
前端
歪歪1001 小时前
Vue原理与高级开发技巧详解
开发语言·前端·javascript·vue.js·前端框架·集成学习