最近在二开组件,涉及到Openlayers,也是第一次接触。
简单学习一下Openlayers。
1、初始化地图
// 设置一些地图的属性
this.view = new View({
center: this._defaultCenter,
zoom,
maxZoom,
minZoom,
constrainOnlyCenter: true,
constrainResolution: true,
zoomFactor: 2,
//extent 视图窗口可视区域,类似amap的brounds
extent: this.extent ?? undefined,
//openlayers 禁止地图旋转 这里加入下面代码
enableRotation: false,
})
// 创建
this.map = new Map({
target, // 容器id
view: this.view,
controls: [],
})
2、openlayers 禁止地图旋转
在new View的时候,加enableRotation: false,
3、给标记点设置样式(icon以及圆角矩形文本框)
(效果)
圆角矩形这段用了该博主的代码(↓下面是链接)
// 创建圆
const circleStyle = new Circle({
radius: 15,
stroke: new Stroke({
color: this.featureColor
}),
fill: new Fill({
color: '#fff'
})
})
// 设置文本样式
let textStyle = {
// 字体样式
font: "12px",
textAlign: "center",
textBaseline: "middle",
fill: new Fill({
color: this.featureColor // 文本颜色
}),
backgroundFill: new Fill({
color: '#fff', // 忘记这个是设置什么的了哈哈哈
}),
}
// 循环生成标记点
const markerList = list.map((spotData, index) => {
// 处理数据,这里根据自己的需要
const { id, lonLat, text, iconKey } = spotData
const uniKey = 'marker_icon_' + iconKey
const coordinate = olProj.fromLonLat(lonLat)
let imageStyle
// 判断是否设置了icon,若没有显示圆
if (index == activeSpotIndex && spotIconText) {
imageStyle = circleStyle
textStyle.padding = [0, 0, 0, 0]
textStyle.offsetY = 0
textStyle.text = '显示的文本内容'
} else {
// 创建icon
imageStyle = new Icon({
anchor: [0.5, 1],
height: this.height,
width: this.width,
src: src,
})
textStyle.padding = [2, 5, 2, 5]
textStyle.offsetY = -50
textStyle.text = '显示的文本内容'
}
// 这里设置文本的圆角矩形文本框
// 绘制圆角矩形
let canvas = document.createElement('canvas')
let context = canvas.getContext('2d')
let length = textStyle.text?.length + 1 || 0
canvas.width = length * 20
canvas.height = 35
let x = 0
let y = 0
let w = canvas.width
let h = canvas.height
let r = 15
// 缩放
context.scale(0.8, 0.8)
context.fillStyle = 'rgba(255,255,255,1)'
// 绘制圆角矩形
context.beginPath()
context.moveTo(x + r, y)
context.arcTo(x + w, y, x + w, y + h, r)
context.arcTo(x + w, y + h, x, y + h, r)
context.arcTo(x, y + h, x, y, r)
context.arcTo(x, y, x + w, y, r)
// 设置阴影
context.shadowColor = 'rgba(0, 0, 0, 0.2)' // 颜色
context.shadowBlur = 5 // 模糊尺寸
context.shadowOffsetX = 2 // 阴影Y轴偏移
context.shadowOffsetY = 2 // 阴影X轴偏移
// ----
context.closePath()
// 填充
context.fill()
textStyle.offsetY = 20
// 标记点
let markerStyle = [
// icon
new Style({
image: imageStyle,
}),
// 文本
new Style({
image: new Icon({
img: canvas,
imgSize: [w, h],
offsetOrigin: 'center',
anchor: [0.4, -0.15],
}),
text: new Text(textStyle)
})
]
// 创建
let feature = new Feature({
id: id,
geometry: new Point(coordinate), // 经纬度
})
feature.set("userSpotData", spotData);
feature.setStyle(markerStyle)
return feature
})
this.markerSource.clear()
this.markerSource.addFeatures(markerList)
4、根据标记点移动视图/地图定位到相应位置并缩放
方法1:
// 直接移动,没有动画
// map.getView().setCenter([longitude, latitude]);
// map.getView().setZoom(zoom);
// 优化后
map.getView().animate({
center: features[0].getGeometry().getCoordinates(),
duration: duration, // 动画持续时间,单位毫秒
});
方法2:
let minX = null; let minY = null; let maxX = null; let maxY = null
// this.markerSource 标注数据源
const features = this.markerSource.getFeatures()
let boundsArry = features[0].getGeometry().getExtent()
if (minX === null) {
minX = boundsArry[0]
minY = boundsArry[1]
maxX = boundsArry[2]
maxY = boundsArry[3]
} else {
minX = Math.min(boundsArry[0], minX)
minY = Math.min(boundsArry[1], minY)
maxX = Math.max(boundsArry[2], maxX)
maxY = Math.max(boundsArry[3], maxY)
}
const bounds = [minX, minY, maxX, maxY]
map.getView()
.fit(bounds, {
'duration': duration,
'padding': [150, 150, 150, 150],
'size': this.map.getSize(), // 考虑地图的大小
'nearest': true, // 如果设置为true,则缩放级别将被舍入到最近的整数
})