前言
好久不见,间隔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)}
绘制圆有两种形式,别离是应用circular
和Circle
这两者有什么区别我也不太分明,它们的入参根本一样,中心点和半径,文档上没有指出半径的单位,第二种办法是百度上搜到的,绘制完经测距测试后是精确的。
增加暗影成果
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)
本次分享就这么多了,下次见~