前言

好久不见,间隔OpenLayers入门第一篇曾经过了很久,为什么迟迟没有后续呢,次要有两个起因,一是因为近期我的项目里应用地图的局部比拟少,二是因为很多时候即便性能做进去了,然而还是不能齐全了解,不是很明确的货色除了贴代码之外也写不了啥,其实第一篇也是很根底很简略的,然而意外的是看的人是最多的,这让我意识到可能即便是贴一下代码对一些人也是有帮忙的,这就是这一篇的次要目标,可能有一些中央会看不懂,然而不要问,问我也不晓得,如果你恰好理解的话非常欢送在评论里分享,感激~

首先来分享一个我无心中找到的教程,http://linwei.xyz/ol3-primer/index.html。尽管是基于v3版本介绍的,很多api可能变了,但还是值得一看,除了OpenLayers自身的介绍,还会有一些天文基础知识的分享,这种绝对全面的中文教程真的很罕见,且看且珍惜。

接下来分享一些罕用的在线地图瓦片资源:

1.高德瓦片,最大反对放大到20级,字体比拟大,然而最近如同又只能到19级了。

http://wprd0{1-4}.is.autonavi.com/appmaptile?x={x}&y={y}&z={z}&lang=zh_cn&size=1&scl=1&style=7

2.高德瓦片,最大反对放大到20级,色彩偏灰绿色。

http://webst0{1-4}.is.autonavi.com/appmaptile?style=7&x={x}&y={y}&z={z}

3.高德瓦片,最大反对放大到18级,最罕用的款式。

http://webrd01.is.autonavi.com/appmaptile?x={x}&y={y}&z={z}&lang=zh_cn&size=1&scale=1&style=8

4.谷歌地图瓦片,最大反对放大到22级,色彩偏绿色。

https://mt0.google.cn/vt/lyrs=m&hl=zh-CN&gl=cn&x={x}&y={y}&z={z}

绘制多边形

import Feature from 'ol/Feature'import Polygon from 'ol/geom/Polygon'import { Vector as VectorSource } from 'ol/source'import { Style, Stroke, Fill } from 'ol/style'import { Vector as VectorLayer } from 'ol/layer'// data为多边形每个点的经纬度坐标数组,[[120.11997452699472, 30.314227730637967],[120.11997452699472, 30.314227730637967],...]function renderArea (data) {    // 创立因素    const features = [        new Feature({            geometry: new Polygon([data])// 应用多边形类型        })    ]    // 创立矢量数据源    const source = new VectorSource({        features    })    // 创立款式    const style = new Style({        stroke: new Stroke({            color: '#4C99F8',            width: 3,            lineDash: [5]        }),        fill: new Fill({            color: 'rgba(255,255,255,0.1)'        })    })    // 创立矢量图层    const areaLayer = new VectorLayer({        source,        style,        zIndex: 1    })    // 增加到地图实例    map.addLayer(areaLayer)}

多边形的绘制很简略,应用几何类型里的多边形类创立一个因素就能够了。

区域两头的名字显示能够通过Overlay叠加层来显示,次要是要计算一下显示的地位:

import Overlay from 'ol/Overlay';import { boundingExtent } from 'ol/extent';import { getCenter } from 'ol/extent';import { fromLonLat } from 'ol/proj';// 获取一个多边形的四个边界点,data:[[120.11997452699472, 30.314227730637967],[120.11997452699472, 30.314227730637967],...]function getExtent (data) {    let minx = 99999999;    let miny = 99999999;    let maxx = -99999999999;    let maxy = -99999999999;    data.forEach((item) => {        if (item[0] > maxx) {            maxx = item[0];        }        if (item[0] < minx) {            minx = item[0];        }        if (item[1] > maxy) {            maxy = item[1];        }        if (item[1] < miny) {            miny = item[1];        }    });    return [Number(minx), Number(miny), Number(maxx), Number(maxy)];}// 也能够间接应用工具办法:boundingExtentfunction getExtent (data) {    return boundingExtent(data)}// 获取范畴的中心点坐标let center = getCenter(getExtent(data));// 显示名称let nameEl = document.createElement('div')nameEl.className = 'name'nameEl.innerHTML = '我是名称'let nameOverlay = new Overlay({    position: fromLonLat(center, 'EPSG:4326'),    element: nameEl,    offset: [0, 0],    positioning: 'bottom-center'})map.addOverlay(nameOverlay)

绘制以米为单位的圆

import Feature from 'ol/Feature'import { circular } from 'ol/geom/Polygon'import { Vector as VectorSource } from 'ol/source'import { getPointResolution } from 'ol/proj'import { METERS_PER_UNIT } from 'ol/proj/Units'import Circle from 'ol/geom/Circle'import { Style, Stroke, Fill } from 'ol/style'import { Vector as VectorLayer } from 'ol/layer'// 两种形式// 1.应用 circular绘制function renderRangeUseCircular (center, radius) {    const features = []    features.push(new Feature({        geometry: circular(center, radius)    }))    return new VectorSource({        features    })}// 2.应用Circle绘制圆function renderRangeUseCircle (center, projection = 'EPSG:4326', radius) {    const view = map.getView()    const resolutionAtEquator = view.getResolution()    const pointResolution = getPointResolution(projection, resolutionAtEquator, center, METERS_PER_UNIT.m)    const resolutionFactor = resolutionAtEquator / pointResolution    radius = (radius / METERS_PER_UNIT.m) * resolutionFactor    const circle = new Circle(center, radius)    const circleFeature = new Feature(circle)    const vectorSource = new VectorSource({        projection: projection    })    vectorSource.addFeature(circleFeature)    return vectorSource}// 绘制function renderRange () {    const source = renderRangeUseCircle(...params)    // const source = renderRangeUseCircular(...params)    const style = new Style({        stroke: new Stroke({            color: '#4C99F8',            width: 3,            lineDash: [5]        }),        fill: new Fill({            color: 'rgba(76,153,248,0.3)'        })    })    rangeLayer = new VectorLayer({        source,        style,        zIndex: 2    })    map.addLayer(rangeLayer)}

绘制圆有两种形式,别离是应用circularCircle这两者有什么区别我也不太分明,它们的入参根本一样,中心点和半径,文档上没有指出半径的单位,第二种办法是百度上搜到的,绘制完经测距测试后是精确的。

增加暗影成果

OpenLayers的款式对象并不反对间接设置暗影成果,所以须要获取到canvas的绘图上下文来自行添加,原理是监听图层的prerender(在一个图层渲染前触发)和postrender(在一个图层渲染后触发)事件,批改canvas`上下文的绘图款式,对整个图层都是有影响的,所以最好把要增加暗影的因素放到一个独自的图层里:

import { Vector as VectorSource } from 'ol/source'import { Style, Stroke, Fill } from 'ol/style'import { Vector as VectorLayer } from 'ol/layer'const source = new VectorSource({    features: []})const style = new Style({    stroke: new Stroke({        color: '#437AF6',        width: 2    }),    fill: new Fill({        color: 'rgba(33,150,243,0.20)'    })})let vectorLayer = new VectorLayer({    source,    style})// 增加暗影vectorLayer.on('prerender', evt => {    evt.context.shadowBlur = 4    evt.context.shadowColor = 'rgba(0,0,0,0.20)'})vectorLayer.on('postrender', evt => {    evt.context.shadowBlur = 0    evt.context.shadowColor = 'rgba(0,0,0,0.20)'})map.addLayer(vectorLayer)

绘制带边框的线段

OpenLayers是不间接反对这种带边框的线段的,所以一种简略的办法是绘制两条线段叠加起来,下面的宽度比上面的低,就有边框成果了:

import Polygon from 'ol/geom/Polygon'import Feature from 'ol/Feature'import { Vector as VectorSource } from 'ol/source'import { Style, Stroke, Fill } from 'ol/style'import { Vector as VectorLayer } from 'ol/layer'// 创立多边形const features = [    new Feature({        geometry: new Polygon([]),    })]// 上层线段,用来做边框,宽度更宽const source = new VectorSource({    features})const style = new Style({    stroke: new Stroke({        color: '#53AA08',        width: 8    }),    fill: new Fill({        color: 'rgba(151,255,201,0.23)'    })})areaLayer = new VectorLayer({    source,    style,    zIndex: 1})map.addLayer(areaLayer)// 下层线段,用来做两头局部,宽度较小const source2 = new VectorSource({    features})const style2 = new Style({    stroke: new Stroke({        color: '#2AE000',        width: 2    })})areaLayer2 = new VectorLayer({    source: source2,    style: style2,    zIndex: 2})map.addLayer(areaLayer2)

本次分享就这么多了,下次见~