功能实现
工作中一般需要解决的一些常见功能
画线并编辑 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
```javascript
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 覆盖物的新坐标