Openlayers 距离环绘制
思路:利用layer的StyleFunction 来使地图移动或者放缩的时候,使圆保持在地图中心
/**
* 绘制距离环
* @param {number} distance 每环间隔距离,单位:米
* @param {array} texts 要显示的内容
* @description 创建了个layer,然后在layer的styleFunction中做了配置,这里搞了6个环,每两个是一组;搞两个的原因是为了在左侧和右侧都显示当前环的尺寸
*/
export function drawDistanceRing(distance, texts) {
const map = window.map
const layer = new VectorLayer({
source: new VectorSource(),
zIndex: 999,
projection: 'EPSG:4326',
style: function (feature) {
const center = map.getView().getCenter()
const proj = map.getView().getProjection()
const [offsetL1, offsetR1, offsetL2, offsetR2, offsetL3, offsetR3] = calcDistanceRingTextOffset(center, distance * 0.9) // 计算每个环标签像素偏移量
return [
new Style({ // 每个style都是一个环
geometry: circular(center, distance * 1, 128),
text: new Text({
text: texts[0],
font: '14px sans-serif',
fill: new Fill({
color: '#e72b19',
}),
offsetX: offsetL1[0],
offsetY: offsetL1[1]
}),
stroke: new Stroke({
color: '#e72b19',
width: 3
})
}),
new Style({
geometry: circular(center, distance * 1, 128),
text: new Text({
text: texts[0],
font: '14px sans-serif',
fill: new Fill({
color: '#e72b19',
}),
offsetX: offsetR1[0],
offsetY: offsetR1[1]
}),
stroke: new Stroke({
color: '#e72b19',
width: 3
})
}),
new Style({
geometry: circular(center, distance * 2, 128),
text: new Text({
text: texts[1],
font: '14px sans-serif',
fill: new Fill({
color: '#e72b19',
}),
offsetX: offsetL2[0],
offsetY: offsetL2[1]
}),
stroke: new Stroke({
color: '#e72b19',
width: 3
})
}),
new Style({
geometry: circular(center, distance * 2, 128),
text: new Text({
text: texts[1],
font: '14px sans-serif',
fill: new Fill({
color: '#e72b19',
}),
offsetX: offsetR2[0],
offsetY: offsetR2[1]
}),
stroke: new Stroke({
color: '#e72b19',
width: 3
})
}),
new Style({
geometry: circular(center, distance * 3, 128),
text: new Text({
text: texts[2],
font: '14px sans-serif',
fill: new Fill({
color: '#e72b19',
}),
offsetX: offsetL3[0],
offsetY: offsetL3[1]
}),
stroke: new Stroke({
color: '#e72b19',
width: 3
})
}),
new Style({
geometry: circular(center, distance * 3, 128),
text: new Text({
text: texts[2],
font: '14px sans-serif',
fill: new Fill({
color: '#e72b19',
}),
offsetX: offsetR3[0],
offsetY: offsetR3[1]
}),
stroke: new Stroke({
color: '#e72b19',
width: 3
})
}),
]
}
})
const feature = new Feature(fromExtent(map.getView().getProjection().getExtent())) // layer得有feature,不然不显示
layer.getSource().addFeature(feature)
map.addLayer(layer)
}
/**
* 移除距离环
*/
export function removeDistanceRing(layer) {
if (layer) {
layer.getSource().clear()
window.map.removeLayer(layer)
}
}
/**
* 计算距离环文字偏移量
* @param {array} location 距离环圆心坐标
* @param {number} distance 每个环间距
* @returns 六个环偏移量
*/
function calcDistanceRingTextOffset(location, distance) {
const point = turf.point(location) // 用到了turf这个库
const destination1R = turf.destination(point, distance, 90, 'meters' ).geometry.coordinates
const destination1L = turf.destination(point, distance, 270, 'meters' ).geometry.coordinates
const destination2R = turf.destination(point, distance * 2, 90, 'meters' ).geometry.coordinates
const destination2L = turf.destination(point, distance * 2, 270, 'meters' ).geometry.coordinates
const destination3R = turf.destination(point, distance * 3, 90, 'meters' ).geometry.coordinates
const destination3L = turf.destination(point, distance * 3, 270, 'meters').geometry.coordinates
const pixelCenter = getPixelFromCoordinate(location)
const pixel1R = getPixelFromCoordinate(destination1R)
const pixel1L = getPixelFromCoordinate(destination1L)
const pixel2R = getPixelFromCoordinate(destination2R)
const pixel2L = getPixelFromCoordinate(destination2L)
const pixel3R = getPixelFromCoordinate(destination3R)
const pixel3L = getPixelFromCoordinate(destination3L)
const offsetR1 = [pixel1R[0] - pixelCenter[0] - 5, pixel1R[1] - pixelCenter[1]]
const offsetL1 = [pixel1L[0] - pixelCenter[0], pixel1L[1] - pixelCenter[1]]
const offsetR2 = [pixel2R[0] - pixelCenter[0], pixel2R[1] - pixelCenter[1]]
const offsetL2 = [pixel2L[0] - pixelCenter[0], pixel2L[1] - pixelCenter[1]]
const offsetR3 = [pixel3R[0] - pixelCenter[0], pixel3R[1] - pixelCenter[1]]
const offsetL3 = [pixel3L[0] - pixelCenter[0], pixel3L[1] - pixelCenter[1]]
return [offsetL1, offsetR1, offsetL2, offsetR2, offsetL3, offsetR3]
}
效果图:
感谢