OpenLayers简介
OpenLayers(https://openlayers.org/)是一个用来帮助开发Web地图应用的高性能的、功能丰富的JavaScript类库,可以满足几乎所有的地图开发需求。
有如下特点:
支持任何XYZ瓦片资源,同时也支持OGC的WMTS规范的瓦片服务以及ArcGIS规范的瓦片服务
支持矢量切片,包括pbf、GeoJSON、TopoJSON格式
支持矢量图层,能渲染GeoJSON、TopoJSON、KML、GML和其他格式的矢量数据
支持OGC制定的WMS、WFS等GIS网络服务规范
支持在移动设备上运行
可以通过css来为地图控件设置样式
面向对象开发方式,在OpenLayers中万物皆对象
和另一个流行的地图库leaflet不同,openLayers完全是用面向对象的方式开发的,且几乎内置了所有地图开发需要的功能,而leaflet核心库只提供基本功能,其他功能都是通过第三方插件进行扩展。使用上来说leaflet更容易上手,OpenLayers上手难度比较大,所以业务可预见较为简单的建议采用leaflet。
OpenLayers虽然很强大,但是因为一切皆对象,所以使用起来很麻烦,再加上无比难看的文档,所以对新手极其不友好,这也是本系列文章的初衷,旨在基于实际业务开发的场景下来沉淀一些内容,来帮助新手使用OpenLayers。
这是本系列的第一篇,主要介绍地图的实例化、基本的要素操作,后续不定期更新。
本文基于OpenLayers v6+版本,代码基于Vue。
npm
i ol
实例化地图
要显示一个基本的地图首先需要提供一个容器,设置好宽高,然后引入OpenLayers,添加一个地图图层,地图服务可以使用内置的一个开源地图OSM,也可以使用其他的在线瓦片服务,比如:百度、高德、天地图、必应、谷歌等,具体服务地址可以自行百度,本文使用的是高德的服务,详情可参考:https://www.jianshu.com/p/e34f85029fd7。
<
div
class
=
"ol-map"
ref
=
"olMap"
>
</
div
>
import
Map
from
'ol/Map'
import
View
from
'ol/View'
import
{ Tile
as
TileLayer }
from
'ol/layer'
import
{XYZ, OSM}
from
'ol/source'
import
{ fromLonLat }
from
'ol/proj'
const
tileLayer =
new
TileLayer({
source
:
new
XYZ({
url
:
'https://webrd01.is.autonavi.com/appmaptile?lang=zh_cn&size=1&scale=1&style=8&x={x}&y={y}&z={z}'
let
map =
new
Map
({
layers
: [tileLayer],
view
:
new
View({
center
: fromLonLat([
120.771441
,
30.756433
]),
zoom
:
15
,
minZoom
:
0
,
maxZoom
:
18
,
constrainResolution
:
true
target
:
this
.$refs.olMap
这样就可以显示一个基本的地图:
可以拖动和缩放,但是不能旋转,如果需要支持旋转,需要加上旋转交互:
import
{
defaults
as
defaultInteractions,
DragRotateAndZoom,
}
from
'ol/interaction'
let
map =
new
Map
({
interactions
: defaultInteractions().extend([
new
DragRotateAndZoom()])
这样就可以按住shift键时通过鼠标来进行旋转地图。
OpenLayers有内置很多开箱即用的控件,常用的使用如下:
import
{ defaults, FullScreen, MousePosition, ScaleLine }
from
'ol/control'
let
map =
new
Map
({
controls
: defaults().extend([
new
FullScreen(),
new
MousePosition(),
new
ScaleLine()
地图也有很多事件,可以监听所需要的事件来进行对应的操作,使用如下:
map.on(
'moveend'
,
e
=>
{
map.on(
'rendercomplete'
,
() =>
{
map.on(
'click'
,
e
=>
{
显示地图基本就到这里,接下来看一些常见的使用场景。
在地图上显示一些自定义元素可以说是最基本也是最常见的需求,如果要显示的元素结构或样式比较复杂,可以使用Overlay,它可以将DOM元素在地图上进行显示,并将随地图一起移动。
import
Overlay
from
'ol/Overlay'
let
el =
document
.createElement(
'div'
)
let
marker =
new
Overlay({
element
: el,
position
: fromLonLat([longitude, latitude],
'EPSG:4326'
),
offset
: [-
17
, -
17
],
autoPan
:
true
,
map.addOverlay(marker)
map.removeOverlay(marker)
如果是显示一个小icon、多边形、线之类的需要使用矢量对象Feature,先看如何显示一个图片icon:
import
Feature
from
'ol/Feature'
import
Point
from
'ol/geom/Point'
import
{ Vector
as
VectorLayer }
from
'ol/layer'
import
{ Vector
as
VectorSource }
from
'ol/source'
import
{ Style, Icon }
from
'ol/style'
let
feature =
new
Feature({
geometry
:
new
Point([
120.12636255813723
,
30.313142215804806
])
feature.set(
'data'
, data)
feature.setStyle([
new
Style({
image
:
new
Icon({
anchor
: [
0.5
,
1
],
size
: [
18
,
28
],
src
:
require
(
'../../assets/images/mouse_location_ing.png'
)
let
source =
new
VectorSource({
features
: [feature]
let
vector =
new
VectorLayer({
source
: source
let vector = new VectorLayer({
source: source,
style: new Style({
image: new Icon({
anchor: [0.5, 1],// 显示位置
size: [18, 28],// 尺寸
src: require('../../assets/images/mouse_location_ing.png')// 图片url
map.addLayer(vector)
上面就实现了添加一个icon要素到地图上,如果要添加多个的话实例化多个Feature就好了,效果如下:
有时还需要支持能拖动要素来修改它的位置,实现这个需要Translate交互的支持:
import
{Translate}
from
'ol/interaction'
let
translate =
new
Translate({
layers
: [vector]
map.addInteraction(translate)
translate.on(
'translateend'
,
(
e
) =>
{
console
.log(e)
translate.on(
'translatestart'
,
(
e
) =>
{
console
.log(e)
除了直接在地图上显示,也可以自己进行添加,即在鼠标点击的位置上添加一个要素,这需要使用到Draw交互:
import
{ Draw }
from
'ol/interaction'
let
draw =
new
Draw({
source
: source,
type
:
'Point'
,
style
:
new
Style({
image
:
new
Icon({
anchor
: [
0.5
,
1
],
size
: [
18
,
28
],
src
:
require
(
'../../assets/images/mouse_location_ing.png'
)
draw.on(
'drawend'
,
(
e
) =>
{
console
.log(e)
map.removeInteraction(draw)
map.addInteraction(draw)
因为icon多了的话不知道某个icon到底代表的是啥,所以常常需要给icon添加一个tooltip,当鼠标移上去的时候显示,怎么实现呢,其实tooltip本质上就是一个DOM元素,上面已经介绍过Overlay了,用它就可以实现,请看:
<
div
class
=
"ol-popup"
ref
=
"olPopup"
>
{{olPopupText}}
</
div
>
import
Overlay
from
'ol/Overlay'
this
.tooltipOverlay =
new
Overlay({
element
:
this
.$refs.olPopup,
positioning
:
'bottom-center'
,
offset
: [
0
, -
30
],
autoPan
:
true
map.addOverlay(
this
.tooltipOverlay)
map.on(
'pointermove'
,
(
e
) =>
{
this
.olPopupText =
''
map.forEachFeatureAtPixel(e.pixel,
(
f, layer
) =>
{
if
(layer !==
this
.vectorLayer || !f.get(
'data'
)) {
return
false
this
.olPopupText = f.get(
'data'
)
this
.tooltipOverlay.setPosition(f.getGeometry().getCoordinates())
这样当鼠标移上去就会显示tooltip:
接下来看看如何绘制多边形,绘制图形用的还是之前的Draw交互:
import
{ Draw }
from
'ol/interaction'
let
source =
new
VectorSource()
let
vector =
new
VectorLayer({
source
: source
map.addLayer(vector)
let
draw =
new
Draw({
source
: source,
type
:
'Circle'
map.addInteraction(draw)
很简单,实例化一个Draw对象,设置一下type就可以了,上面设置的是Circle,绘制出来的是圆:
接下来看看正方形和长方形,在上面的例子之上修改:
import
{ createRegularPolygon, createBox }
from
'ol/interaction/Draw'
let
draw =
new
Draw({
source
: source,
type
:
'Circle'
,
geometryFunction
: createBox()
其他类型只要设置对应的type就可以了,比如绘制不规则多边形为POLYGON,具体类型可以查看文档:https://openlayers.org/en/latest/apidoc/module-ol_geom_GeometryType.html。
实际的使用场景还会存在需要修改存在的多边形的情况,需要用到Modify交互:
import
{ Modify }
from
'ol/interaction'
let
modify =
new
Modify({
source
map.addInteraction(modify)
现在就可以拖动多边形的端点来进行修改了。
以上对几何体的操作和显示用的都是自带的默认样式,如果有自定义样式需求的话可以通过style配置进行修改,对要素的基本使用就到这里。
获取地图当前区域的范围
为了性能考虑,如果是在地图上显示要素的话最好是只显示当前显示区域内的要素,要显示的数据一般从后端进行请求,那么可以把当前区域的范围发送给后端,后端只返回这个区域内的数据就好了,那么就需要获取当前的范围:
let
range = map.getView().calculateExtent(map.getSize())
let
state = {
minLon
: range[
0
],
minLat
: range[
1
],
maxLon
: range[
2
],
maxLat
: range[
3
],
zoomLevel
: map.getView().getZoom()
因为本人也是刚开始入门,所以可能存在一些不对的地方或有一些更好的实现方式,欢迎指出。
来源:
https://www.cnblogs.com/wanglinmantan/p/15101609.html
用js的人都应该知道eval()函数吧,虽然该函数用的极少,但它却功能强大,那么问题来了,为什么不常用呢?原因很简单,因为eval()函数是动态的执行其中的字符串,里面有可能是脚本,那么这样的话就有可能引发系统的安全问题,所以能不用就不用,但至少也要知道它的用法。
eval()函数的作用简单来说就是用来把括号中的字符串当作代码来执行,举个简单的例子,e... (
继续浏览
)
最近在提炼一个功能的时候发现可配置项过多,如果全都耦合在一起,首先是代码上不好维护、扩展性不好,其次是如果我不需要该功能的话会带来体积上的冗余,考虑到现在插件化的流行,于是小小的尝试了一番。
先介绍一下这个库的功能,一个简单的让你可以在一个区域,一般是图片上标注一个区域范围,然后返回顶点坐标的功能:
话不多说,开撸。
插件我理解就是... (
继续浏览
)
flex全称Flexible Box模型,顾名思义就是灵活的盒子,不过一般都叫弹性盒子,所有PC端及手机端现代浏览器都支持,所以不用担心它的兼容性,有了这玩意,妈妈再也不用担心我们的布局。
先简单介绍一下,要使用flex布局,需要先给一个容器元素设置display:flex让它变成flex容器,然后其所有的直接子元素就变成flex子元素了,在flex里... (
继续浏览
)
TypeScript已经出来很多年了,现在用的人也越来越多,毋庸置疑,它会越来越流行,但是我还没有用过,因为首先是项目上不用,其次是我对强类型并不敏感,所以纯粹的光看文档看不了几分钟就心不在焉,一直就被耽搁了。
但是,现在很多流行的框架都开始用TypeScript重构,很多文章的示例代码也变成TypeScript,所以这就很尴尬了,你不会就看不... (
继续浏览
)
npx使用教程#
今晚在学习Vue-Cli时, 由于突发奇想想试试最新的@4.x.x版本, 但是本地全局安装的脚手架版本是@2.x.x的, 因为不想污染全局于是就想到用npx命令, 一路上踩坑不断, 为了以后能够更好的使用npx并区分其跟npm的指令, 就有了本篇笔记
npm 是从5.2版开始, 增加(自带)了 npx 命令。 如果发现没安装请手动安... (
继续浏览
)
思维导图是一种常见的表达发散性思维的有效工具,市面上有非常多的工具可以用来画思维导图,有免费的也有收费的,此外也有一些可以用来帮助快速实现的JavaScript类库,如:jsMind、KityMinder。
本文会完整的介绍如何从头实现一个简易的思维导图,最终成果预览:https://wanglin2.github.io/mind-map/。
... (
继续浏览
)
本文是对the-super-tiny-compiler仓库的翻译,原文章(代码):https://github.com/jamiebuilds/the-super-tiny-compiler/blob/master/the-super-tiny-compiler.js
今天我们一起动手写一个编译器,但不是我们平常所说的编译器,而是一个超级超级小的编... (
继续浏览
)
很高兴能够写这篇文章通知大家Wechaty的web协议又能大放光彩了,如果之前你的微信提示不能登录web端,那么这个更新将会是你的福音。因为现在的wechaty-puppet-wechat已经支持使用UOS微信桌面版协议登录,赶快来尝试一下吧。
关键依赖:npm install wechaty-puppet-wechat --... (
继续浏览
)