Contents
功能实现
- 工作中一般需要解决的一些常见功能
画线并编辑 api:draw, modify
添加绘制功能 draw
- 注意事项: 在添加绘制功能之前,应提前先在地图渲染时,为绘制功能添加一个矢量图层
import VectorLayer from 'ol/layer/Vector' import VectorSource from "ol/source/Vector" let drawsource = new VectorSource() let drawvector = new VectorLayer({ source: drawsource, }); map.addLayer(drawvector)
- 添加绘制功能
import {Draw, Snap} from 'ol/interaction' let draw = new Draw({ source: drawsource, //之前预先创建的图层的 `drawsource` } map.addInteraction(draw) let snap = new Snap({source: drawsource}) //snap 捕捉并处理绘制以及修改时的矢量元素 map.addInteraction(snap)
绘制中设置动态样式
- 绘制中动态样式,是在用户绘制过程中显示的样式,并非绘制结束最终的样式
- openlayers 中 Draw 对象有一个 Style 属性, Style 可以是一个样式数组,也可以是一个函数(返回一个样式数组; 这个函数有两个参数 分别是: fearture(绘制中的), resolution(视图的分辨率))
- 这里我们的思路就是: 通过style 函数的fearture 参数来获取绘制点,并为之添加样式
是在添加绘制功能的时候添加样式 import {Draw, Snap} from 'ol/interaction' let draw = new Draw({ source: drawsource, //之前预先创建的图层的 `drawsource` style(feature, r){ // **重点: 此处的 feature 是跟随鼠标的变化实时的数据,不是你绘制的点的数据 ** // ** 指定绘制点添加样式** :用到 Style 的一个可以指定 geometry 来添加样式 let coords = feature.getGeometry().getCoordinates() let styles = [] for(let i in coords){ styles.push(new Style({ geometry: new Point(coords[i]) //指定点 ... //此处写你的样式 })) } return styles } } map.addInteraction(draw)
绘制结束事件监听
- openlayers 中的 draw 绘制结束事件监听api:
drawend
, 回调函数有一个DrawEvent
(feature: Feature {…}, target: Draw{…}, type: "drawend"
) 的参数, 此处的是你最终绘制的DrawEvent.feature
draw.on('drawend', (drawEvent)=>{ let feature = drawEvent.feature ... //进行各种操作 })
添加修改功能 modify
- 注意事项:修改功能是添加在矢量图层上的,所以需在添加图层的时候加载
let modify = new Modify({ source: drawsource }) map.addInteraction(modify)
修改中的动态样式
- openlayers modify 有一个
modifyend
的事件,回调函数参数:ModifyEvent
(features: Collection {…}, mapBrowserEvent: MapBrowserEvent {…}, target: Modify {…}, type: "modifyend"
), 我们此处使用ModifyEvent.features
modify.on('modifyend', (e)=>{ let feature = e.features.array_[0] ... //进行各种操作 })
坐标转换
- openlayers 默认坐标系是同谷歌地图一样的
EPSG:3857
, 国内常用的坐标系是84坐标系EPSG:4326
,此时坐标系转换功能就是必需的了
参数名 | 参数描述 |
---|---|
coordinate | 坐标 |
source | 坐标的坐标系 |
destination | 目标坐标系 |
import { transform } from 'ol/proj'
let oldCoord = [13031076.441730658, 4735129.733960388] //EPSG:3857
let oldCoord84 = [117.16932799710696, 39.088029694977024] //EPSG:4326
let coordinate84 = new transform(oldCoord, "EPSG:3857", "EPSG:4326"); //转换为84坐标系
let coordinate = new transform(oldCoord84, "EPSG:3857", "EPSG:4326"); //转换为Google Web 墨卡托坐标系
坐标比较
- 在做绘制和修改功能时,不免需要进行前后坐标的对比,而坐标是一个数组模式的数据,这就涉及到数组的对比方式了。
let oldCoordinate = [13031076.441730658, 4735129.733960388] let newCoordinate = [13031152.878758943, 4733983.178536111] oldCoordinate.toString() === newCoordinate.toString() //此处使用转换为字符串进行比较,数组的顺序与值同时相同才能代表坐标的相同
地图实现蒙层
- 给地图添加一层polygon,并置于底层
单击地图事件监听
- openlayers 中的 map对象有一个
singleclick
事件,回调函数参数:
MapBrowserEvent {type: "singleclick", target: Map, map: Map, frameState: {…}, originalEvent: PointerEvent, pixel_: Array(2), target: Map, type: "singleclick", coordinate: Array(2), pixel: Array(2)}
map.on('singleclick', (e)=>{
//需要获取到矢量图层可以使用: map.forEachLayerAtPixel(pixel, callback, opt_options), 获取坐标: map.getCoordinateFromPixel(pixel)
map.forEachFeatureAtPixel(e.pixel, (feature)=>{
//...数据处理 此处为你点击的 feature
}, {
//options: layerFilter | hitTolerance | checkWrapped})
})
地图可视范围监听
- 此处是在地图的可视范围发生变化时,通过监听地图的
moveend
事件进而获取当前的可视范围import {getTopLeft, getTopRight, getBottomLeft, getBottomRight} from 'ol/extent' map.on('moveend', (event)=>{ //获取可视化区域得范围 let coods = event.map.getView().calculateExtent( event.map.getSize()), postcooders = [getTopLeft(coods), getTopRight(coods), getBottomRight(coods) ,getBottomLeft(coods), getTopLeft(coods)]; //可视区域为一个多边形,需是闭合的 })
串线多样式编辑
- openlayers
Style
对象可以接收一个数组,对于同一条串线可以有多种不同的样式,只需按照你的样式顺序添加即可import Feature from 'ol/Feature'; import LineString from 'ol/geom/LineString'; import Style from 'ol/style/Style'; let lineFeature = new Feature(new LineString([coordinates])) let yourStyle1 = new Style({...}), yourStyle2 = new Style({...}); let yourStyles = [yourStyle1, yourStyle2, ...] //依次添加要用 Array.prototype.push(), 解构语言是不支持的 lineFeature.setStyle(yourStyles)
带箭头的串线样式编辑
- 大概思路: 获取串线的最后两个点=>计算出串线的走向=>为最终点添加箭头图标(含串线走向的属性)
import {Point} from 'ol/geom' //start 串线走向计算第一个点, end 串线最终点, iconImg 串线最终的箭头图标 arrowIcon(start, end, iconImg){ let feature = new Feature({ geometry: new Point(end), }); let rotation = Math.atan2(end[0] - start[0], end[1] - start[1]); //计算串线走向 feature.setStyle( new Style({ image: new Icon({ anchor: [0.5, 0.5], src: iconImg, rotateWithView: true, // 图标旋转到串线走向 rotation: rotation, //图标旋转到串线走向 ... }), }) ); return feature },
绘制多边形 (闭合的形状)
- 多边形是一个闭合的形状,所以坐标组第一和最后一个坐标一样
import { Polygon } from 'ol/geom' // coords = [[long, lat],[long, lat],[long, lat], ...] let yourPolygon = new Polygon([coords]) //...更多api请查看官网
覆盖物的实时位置监听
- openlayers overlay 有一个
setPosition
的方法, 只需接收到数据,使用此方法即可修改覆盖物的位置`<div id="overlayEl" ><img src="..."></div>` import { Overlay } from "ol" let yourOverlay = new Overlay( { id: "realair", element: document.getElementById("realAir"), position: this.coordTransform(realFeatures), positioning: "center-center", offset: [3, 10] }) map.addOverlay(yourOverlay); yourOverlay.setPosition(newCoordinate) //newCoordinate 覆盖物的新坐标
转载请注明:EZLOST » 前端开发之:openlayers框架,地图相关开发中常见功能