关于javascript:OpenLayers入门一

20次阅读

共计 6324 个字符,预计需要花费 16 分钟才能阅读完成。

OpenLayers 简介

OpenLayers(https://openlayers.org/)是一个用来帮忙开发 Web 地图利用的高性能的、功能丰富的 JavaScript 类库,能够满足简直所有的地图开发需要。

有如下特点:

  1. 反对任何 XYZ 瓦片资源,同时也反对 OGC 的 WMTS 标准的瓦片服务以及 ArcGIS 标准的瓦片服务
  2. 反对矢量切片,包含 pbf、GeoJSON、TopoJSON 格局
  3. 反对矢量图层,能渲染 GeoJSON、TopoJSON、KML、GML 和其余格局的矢量数据
  4. 反对 OGC 制订的 WMS、WFS 等 GIS 网络服务标准
  5. 反对在挪动设施上运行
  6. 能够通过 css 来为地图控件设置款式
  7. 面向对象开发方式,在 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'

// fromLonLat 办法能将坐标从经度 / 纬度转换为其余投影

// 应用内置的 OSM
//const tileLayer = new TileLayer({//    source: new OSM()
//})
// 应用高德
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// 因为存在非整数的缩放级别,所以设置该参数为 true 来让每次缩放完结后主动缩放到间隔最近的一个整数级别,这个必须要设置,当缩放在非整数级别时地图会糊
    }),
    target: this.$refs.olMap// DOM 容器
})

这样就能够显示一个根本的地图:

能够拖动和缩放,然而不能旋转,如果须要反对旋转,须要加上旋转交互:

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 => {// console.log('地图挪动', e)
})
map.on('rendercomplete', () => {// console.log('渲染实现')
})
map.on('click', e => {// console.log('地图点击', 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)
// 设置款式,这里就是显示一张图片 icon
feature.setStyle([
    new Style({
        image: new Icon({anchor: [0.5, 1],// 显示地位
          size: [18, 28],// 尺寸
          src: require('../../assets/images/mouse_location_ing.png')// 图片 url
        })
    })
])
// 矢量源
let source = new VectorSource({features: [feature]
})
// 实例化的时候也能够不增加 feature,后续通过办法增加:source.addFeatures([feature])
// 清空 feature:source.clear()

// 矢量图层
let vector = new VectorLayer({source: source})
// 款式除了能够设置在单个 feature 上,也能够对立设置在矢量图层上
/*
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)
// 能够监听一下拖动开始和完结的事件,拖动后的经纬度能够从 e 外面获取
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')// 图片 url
        })
    })
})
// 监听实现事件
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'

// 创立 Overlayer
this.tooltipOverlay = new Overlay({
    element: this.$refs.olPopup,
    positioning: 'bottom-center',// 依据 position 属性的地位来进行绝对点位
    offset: [0, -30],// 在 positioning 之上再进行偏移
    autoPan: true
})
map.addOverlay(this.tooltipOverlay)

// 给地图绑定鼠标挪动事件,检测鼠标地位所在是否存在 feature,如果是指标 feature 的话就显示 tooltip
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'

// createRegularPolygon 办法执行后返回一个创立正方形的 geometryFunction
// createBox 办法执行后返回一个创立长方形的 geometryFunction

let draw = new Draw({
    source: source,
    type: 'Circle',// 没错,还是 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()// 以后缩放级别,缩放级别可用来判断是否要将因素聚合进行显示
}

再会

因为自己也是刚开始入门,所以可能存在一些不对的中央或有一些更好的实现形式,欢送指出。

正文完
 0