前言: 折磨了好几个小时,终于做出了正确的效果,如果你也受苦于使用circle 生成 通过offsetX或者Y 文字始终不能到他准确的位置,那先恭喜你,至少你获得了一种可以实现的方案。
问题描述
我们需要实现如图所示的范围扩散的圆,同时需要准确的显示在圆的边上的文字,至于颜色。。这个想必不用我多提。
主要思路
如果offsetX、offsetY 文字 不可以到达圆的边上也就是我们想要的准确的位置,那我们是否可以通过获取coordinator坐标,去通过这个坐标实现这个文字的正确显示位置,结论是可以,因为我做出来了。(ps:这不是废话吗),所以问题的核心在于如何获取到准确的位置即coordinator坐标,那首先根据中心点绘制的圆是必须的,因为不论如何,除开文字之后,你是必须在这个中心点上绘制圆。而如何通过这个已经绘制的圆去获取他的边上的坐标呢?ol中 可以对圆形进行转换绘制,变为polygon,
本篇文章使用的是fromCircle这个方法,将一个circle geometry 转换为polygon,得到了polygon多边形之后,由于polygon是由一个线性环数组构成的,我们应该可以通过这个线性环数组通过getCoordinates去获取到他的坐标。思路可能出乎你意料的简单、开始code吧
参考代码
/**
* 根据经纬度坐标画圆 注意 注意该函数 不可轻易复用!问题多多。。
* @param {*} centerPosition 中心点经纬度坐标
* @param {*} radius 半径 单位为米 可以为空,默认值为2000
* @param {*} callback 自定义设置 比如style 比如 设置属性 等等
* @param {*} color 线条颜色
* @param {*} text 提示文字
* @return {*} features
*/
drawCircle(centerPosition, radius = 2000, callback, color = '#000', text = '') {
let features = []
for (let i = 0; i < centerPosition.length; i++) {
let EPSGTransCoord = fromLonLat(centerPosition[i])
let circle = new Circle(EPSGTransCoord, radius)
let feature = new Feature({
geometry: fromCircle(circle),
})
let coord = feature.getGeometry().getLinearRings()[0].getCoordinates()[0]
let featureText = new Feature({
geometry: new Point(coord)
})
featureText.setStyle(new Style({
text: new Text({
font: '14px Microsoft YaHei',
text: text,
textAlign: "right", //对齐方式
textBaseline: "middle", //文本基线
fill: new Fill({
color: color
}),
offsetX: -5
})
}))
if (callback !== undefined && typeof callback === 'function') {
callback(feature, i, color)
}
features.push(feature,featureText)
}
return features;
}
上面这段代码是我封装起来的一个js文件中,类中的一个方法,这里说明一下:设置callback的意义在于给这个feature增加独特的样式、属性、用于识别获取该feature或者个性化,好吧,尽管我承认我这个方法写糟糕了。
// 自动站距离 画圆
drawCircleByStation: function({obtData,mapObj,map2d}){
let stationData = obtData
let layer = mapObj.createVectorLayer()
let source = mapObj.createVectorSource()
let positions = []
for (let i in stationData) {
let curData = stationData[i]
let [lon, lat] = [curData.lon, curData.lat]
positions.push([lon, lat])
}
// 首先颜色配置、接着到 虚线 、 接着 到半径 依次生成features 将其放入该图层
let colorArray = ['red','orange','yellow','blue']
function circleCallback(feature,index,color){
feature.setStyle(setCircleStyle(color))
}
let feature2km = mapObj.drawCircle(positions,2000,circleCallback,colorArray[0],'2km')
let feature3km = mapObj.drawCircle(positions,3000,circleCallback,colorArray[1],'3km')
let feature4km = mapObj.drawCircle(positions,4000,circleCallback,colorArray[2],'4km')
let feature5km = mapObj.drawCircle(positions,5000,circleCallback,colorArray[3],'5km')
let allFeatures = feature2km.concat(feature3km).concat(feature4km).concat(feature5km)
source.addFeatures(allFeatures)
layer.setSource(source)
map2d.addLayer(layer)
},
上面这段代码已经尽可能的简洁明了,创建图层、源、获取经纬度数组,传入drawcircle方法画出圆、callback中设置属性、颜色、文字、
export function setCircleStyle(color) {
return new Style({
stroke: new Stroke({
color,
width: 1,
lineDash: [10]
}),
})
}
这个也是一个js文件中导出的一个方法,所以如果你想解决问题,注意动动脑子,结合自己的实际情况出发。
那么如果你顺利的过完了代码,你会发现,其中的核心应该在于获取这个coordinator数组,emmm,所以你大可以通过这个思路,打印出相关的coordinator数组的长度,然后给他加上把这个length / 4 3 2 1 - 1试试,就可以实现左右上下的标记文字了,接着通过你想要的方式设置文本的对齐方式,如果需要间距这个时候使用offsetX,Y 也丝毫不会违和了。