开源地图库OpenLayers的简单使用
引言
最近在学习可视化的东西,这让我想起了一些以前用过的图表库,其实我在日常做的大多是普通的需求,可视化方面应用的并不多,只是偶尔会因为个别特殊的需求,去借助一些图表库来实现图表的展示,这些普通的图表库,在使用上都大差不差,并没有什么太大的区别,但是某些特殊的图表库,比如地图库,在使用上和一些普通的图表,还是存在一些不同,现在想一想还是需要做一些记录,因为我没有在当时使用的时候及时记录,导致我现在对OpenLayers的使用也有一点模糊了,只能借助代码来回忆,所以我现在把它的简单使用做一次整理。
其实一开始我选择使用的是比较普遍的高德地图,但是需求做到后面,我才意识到当时做的项目是要部署在内网的,当时就有点傻眼了,因为我对WebGIS也并不熟悉,所以就上网匆匆的搜索有什么容易上手使用的开源地图库,然后锁定了OpenLayers这个库。
OpenLayers使用起来不像高德地图那么方便,因为部署的是内网环境,需要自己准备瓦片服务,还记得当时下载地图瓦片也下载了很久,因为要准备不同比例的地图瓦片,不过幸好当时只需要下载杭州一个城市的瓦片。
准备工作
虽然之前我是在React的项目中使用OpenLayers的,但OpenLayers的使用与项目的具体框架并没有太大的关系,所以我们只需要使用script标签引入OpenLayers,就可以在项目中使用这个开源地图库了。
因此我们的准备工作,只需要一个引入OpenLayers的页面,然后在页面上准备一个div,来作为地图的容器就可以了,另外在这个例子中我使用了systemjs来进行浏览器端的包管理,不用也是可以的;当然,地图瓦片也是需要提前准备的。
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport"
content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>OpenLayers demo</title>
<script type="systemjs-importmap">
{
"imports": {
"ol": "https://cdn.jsdelivr.net/npm/ol@v8.2.0/dist/ol.js"
}
}
</script>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/ol@v8.2.0/ol.css">
<script src="https://cdn.jsdelivr.net/npm/systemjs@6.8.3/dist/system.js"></script>
<script src="https://cdn.jsdelivr.net/npm/systemjs@6.8.3/dist/extras/use-default.js"></script>
</head>
<body>
<div id="map" style="width: 500px; height: 500px;"></div>
</body>
</html>
地图瓦片
地图瓦片是什么呢?简单来说,它是地图视图的组成单元,也就是说,地图的视图是由一张张的瓦片拼凑而成。但是地图的使用一般而言不是静态的,通常在使用中我们需要对地图进行缩放交互,来进行更细致的观察。所以我们一般需要准备多个比例下的地图瓦片,具体的可以根据需求来确定。
虽然当时我查到可以由后端部署服务来提供瓦片,但因为当时比较匆忙,我没来得及仔细研究,又觉得说本来这块工作量之前也并不了解,前端这边如果能直接处理就处理了,所以就用地图瓦片下载器自己去下载了瓦片,然后部署到一个静态服务下面;现在对于demo的编写倒也是一个好处,可以方便前端的独立展示。
实现效果
因为是简单的使用,所以这里我们主要实现地图的展示、放大缩小等简单的功能,以及一些简单的交互处理。
具体实现
总体来说,Openlayers的使用并不复杂,普通的使用通过查阅API文档完全可以应对。
首先我们提前把下载好的地图瓦片放到服务目录下。
然后是最基本的,使用
System.import方法引入ol依赖const ol = await System.import('ol');
然后我们关注三个主要的类,分别是Map、View和TileLayer,这是我们用于构筑地图的主要部分
const OlMap = ol.Map,
View = ol.View,
TileLayer = ol.layer.Tile;
现在我们就可以通过new Map来创建新的地图对象
const map = new OlMap({
target: 'map',
view: new View({
center: [120.212, 30.208],
projection: 'EPSG:4326',
zoom: 9,
maxZoom: 17,
minZoom: 7
}),
});
其中target用于指定盛装地图的容器;
在创建地图对象的时候,会使用到View这个类,代表地图的二维视图。我们可以在视图中通过经纬度数组指定视图的中心,View默认使用EPSG3857坐标系设置,我们也可以通过projection选项来修改坐标系,之前我使用的时候比较匆忙,没有注意到这一块,还很曲折的通过
fromEPSG4326方法来把4326的经纬度转换为3857坐标系;zoom选项用于定义视图初始分辨率的缩放级别,这里我当时是用了9这个级别,我感觉比较合适,当然具体的设置要看项目需求;然后我们可以通过maxZoom和minZoom这两个选项限制最大和最小的缩放级别。现在我们就可以看到,页面上其实已经生成地图容器了,已经能看到放大缩小的操作按钮了,只是说还没有贴上瓦片,所以这时候的地图还比较抽象。
接下来我们就需要用到之前准备的瓦片了,用于给map对象设置layers图层
layers选项接收的是一个数组,也就是说可以给地图配置多个图层;这里我们使用刚刚引入的TileLayer这个类来创建一个图层;另外我们还需要使用一个XYZ的类,来指定瓦片服务的地址。// ...
const XYZ = ol.source.XYZ;
const map = new OlMap({
target: 'map',
view: new View({
center: [120.212, 30.208],
projection: 'EPSG:4326',
zoom: 9,
maxZoom: 17,
minZoom: 7
}),
layers: [
new TileLayer({
source: new XYZ({
url: './maps/{z}/{x}/{y}.png'
})
})
]
});
至此我们就可以在页面上看到地图的展示了,打开控制台我们也可以看到对地图瓦片的请求,请求的是maps/9目录下的瓦片,我们也能注意到,有一些404的请求,这是因为view图层中的部分地图瓦片我们没有准备,通过在页面上检查元素,也可以看到map容器中确实存在一部分没有贴上瓦片,这通常来说没什么关系,可以不用管;可以看到当使用鼠标滚动缩放地图的时候,也会去请求相应缩放比例的地图瓦片。
添加简单的交互事件
最后来添加一些简单的交互。
之前我做的需求中需要根据接口返回的数据批量标注地图上的点,但是因为现在没有数据,这里就实现一些简单的交互吧。const olExtent = ol.extent;
map.on('moveend', e => {
console.log('zoom', map.frameState_.viewState.zoom);
const extent = map.frameState_.extent;
console.log('extent', extent);
console.log('TopLeft', olExtent.getTopLeft(extent));
console.log('BottomRight', olExtent.getBottomRight(extent));
});
我们可以通过zoom获取视图的缩放级别,通过extent获取视图的经纬度范围,还可以进一步通过extent的getTopLeft和getBottomRight分别获取左上角的经纬度和右下角的经纬度;这样我们就可以在缩放视图和移动图层时根据视图的经纬度范围来加载相应的数据。
const Feature = ol.Feature;
const Point = ol.geom.Point;
const Style = ol.style.Style,
CircleStyle = ol.style.Circle,
Fill = ol.style.Fill,
Stroke = ol.style.Stroke;
const VectorSource = ol.source.Vector,
VectorLayer = ol.layer.Vector;
let count = 0;
map.on('click', e => {
const features = [];
console.log(e.coordinate); // 获取坐标 const iconFeature = new Feature({
geometry: new Point(e.coordinate),
name: count ++,
location: e.coordinate
});
const style = new Style({
image: new CircleStyle({
radius: 10,
fill: new Fill({
color: '#f49d41'
}),
stroke: new Stroke({
color: '#836365',
width: 1
})
})
});
iconFeature.setStyle(style);
features.push(iconFeature);
const vectorSource = new VectorSource({
features
});
const vectorLayer = new VectorLayer({
source: vectorSource,
opacity: 0.8
});
map.addLayer(vectorLayer);
});
我们还可以在处理地图的鼠标点击事件时,获取鼠标点对应的经纬度,通过Feature类给地图添加标注,再通过Style类给标注设置样式;也可以在添加新标注前移除旧的标注。
const layers = map.getLayers();
layers.forEach(item => {
if(item instanceof VectorLayer) map.removeLayer(item);
});
到这里我们就完成了OpenLayers的简单使用,如果有感兴趣的小伙伴,可以去OpenLayers的GitHub和官方文档再去进一步的了解。
以下是运行效果:

整体代码参考这个CodePen
开源地图库OpenLayers的简单使用的更多相关文章
- Openlayers自定义简单popup
OpenLayers中可以使用很多种类型的popup,大家可以到Openlayers的 popupMatrix.html示例中看.之前存在这样一个错误的想法:popup和marker是绑定的,要有po ...
- GitHub开源库排名一百的简单介绍,值得收藏!
GitHub Android Libraries Top 100 简介 本项目主要对目前 GitHub 上排名前 100 的 Android 开源库进行简单的介绍, 至于排名完全是根据 GitHub ...
- android 开源图表库MPChart最简单使用方法示例教程Demo--折线图 柱状图
转载请注明本文出处:http://blog.csdn.net/wingichoy/article/details/50428246 MPChart是android上一款强大的图表开源库,他可以轻松的绘 ...
- Xunsearch迅搜(基于 xapian+scws 的开源中文搜索引擎)安装与简单使用
今天鼓捣了xunsearch,感觉官方指南写得挺详细,于是按照指南一步一步走,但是感觉越看越凌乱,像看API一样,新手看得特费劲,网上也少有新手教程,于是略过今天的歪路,记录一下我的安装步骤. Xun ...
- 高性能、高容错、基于内存的开源分布式存储系统Tachyon的简单介绍
Tachyon是什么? Tachyon是一个高性能.高容错.基于内存的开源分布式存储系统,并具有类Java的文件API.插件式的底层文件系统.兼容Hadoop MapReduce和Apache Spa ...
- Android开源项目pulltorefresh分析与简单使用
在Android开发中有时我们须要訪问网络实时刷新数据.比方QQ好友在线状态最新信息,QQ空间须要显示很多其它的好友动态信息,EOE论坛client显示很多其它的文章帖子信息等.android-pul ...
- visual studio 2015引入开源控件DockPanel(最简单的方法)
一.DockPanel简介 DockPanel是一个开源控件,能够实现子窗口的浮动,在官方给的demo有演示,在vs2017微软已经集成进入常用控件中.我主要使用的是多窗口浮动,和tabControl ...
- 开源中文检索引擎Coreseek简单使用
Coreseek结合MySQL使用简单示例,如下所示: echo 北京 | iconv -f gbk -t utf-8 | search -c D:\web\coreseek\etc\csft_mys ...
- (转)64位开源处理器Rocket的源代码简单介绍
转载地址: http://blog.csdn.net/leishangwen/article/details/46604819 最近大概阅读了一下UCB发布的Rocket处理器的源码,对源代码各个文件 ...
- leaflet开源地图库源码 浏览器&移动设备判断(browser.js)备份
<script> var isIe = !-[1,]; // alert('ie9 之前'+isIe); var ie = 'ActiveXObject' in window; //ale ...
随机推荐
- Cookies 完全指南
我们是袋鼠云数栈 UED 团队,致力于打造优秀的一站式数据中台产品.我们始终保持工匠精神,探索前端道路,为社区积累并传播经验价值. 本文作者:佳岚 前言 Cookie实际上是一小段的文本信息,它产生的 ...
- 《最新出炉》系列初窥篇-Python+Playwright自动化测试-14-playwright操作iframe-番外篇
1.简介 通过前边三篇的学习,想必大家已经对iframe有了一定的认识和了解,今天这一篇主要是对iframe的一些特殊情况的介绍和讲解,主要从iframe的定位.监听事件和执行js脚本三个方面进行展开 ...
- 纯干货!一文get昇腾Ascend C编程入门全部知识点
本文分享自华为云社区<昇腾Ascend C编程入门教程>,作者:昇腾CANN . 2023年5月6日,在昇腾AI开发者峰会上,华为正式发布了面向算子开发场景的昇腾Ascend C编程语言. ...
- VisionPro学习笔记(3)——BeadInspectTool
如果需要了解其他图像处理的文章,请移步小编的GitHub地址 传送门:请点击我 如果点击有误:https://github.com/LeBron-Jian/ComputerVisionPractice ...
- WebStrom提交代码到GitLab报错Error: Cannot find any-observable implementation nor global.Observable.
项目场景: 前端代码完成后,提交代码 问题描述 提交代码到GitLab时,因自动检测机制导致项目提交失败 C:\D\insper\inspur_works\custom-manage-front\no ...
- Webpack性能优化 SplitChunksPlugin的使用详解
使用前景 在vue.react等使用webpack为项目打包工具的前端项目,在开发过程中,随着项目功能的逐渐增加,项目整体体积的不断增加,打包的时长和打包后部署的项目体积也在不停的增长,这样可能会导致 ...
- Solution -「CF 1096E」The Top Scorer
Description Link. 小明在打比赛,包括小明自己一共有 \(p\) 名选手参赛,每个人的得分是一个非负整数.最后的冠军是得分最高的人,如果得分最高的人有多个,就等概率从这些人中选一个当冠 ...
- LDA主题模型讲解及代码Python实现
目录 1. LDA主题模型详解 1.1 Beta/Dirichlet 分布的一个性质 1.2 LDA-math-MCMC 1.2.1 重要理解 1.3 Gibbs Sampling 2. 所需工具库 ...
- MySQL实战实战系列 06 全局锁和表锁 :给表加个字段怎么有这么多阻碍?
今天我要跟你聊聊 MySQL 的锁.数据库锁设计的初衷是处理并发问题.作为多用户共享的资源,当出现并发访问的时候,数据库需要合理地控制资源的访问规则.而锁就是用来实现这些访问规则的重要数据结构. 根据 ...
- .Net7自定义GC垃圾回收器
1.前言 CLR和GC高度耦合,.Net7里面分离CLR和GC,则比较容易实现这件事情.本篇来看下,自定义一个GC垃圾回收器. 2.概述 这里首先演示下自定义GC垃圾回收后的效果. 1.下载Custo ...