一开始找了Leaflet.hotline,发现报错用不了,可能1.9.3的版本不支持。后面换成leaflet-polycolor,但有个很坑的问题是每个坐标节点都需要一个颜色才能完成渐变,一般来说这是不可能提供这么多颜色。后来想了下根据节点数量自己算渐变的颜色,再加到线上是否可以实现,答案是:可以!
首先载入文件
import leafletPolycolor from 'leaflet-polycolor';
leafletPolycolor(L);
但比较坑爹,可能是配置问题,里面的a?.b、aa ?? bb 这些运算符都会报错,只能改掉之后单独导入个文件
import leafletPolycolor from '@/assets/script/leaflet-polycolor.js';
leafletPolycolor(L);
继续,获取geojson转成经纬度数组。这个也比较坑,只支持这样的格式[[lat,lng],[lat,lng],.....]
getGeometryData(coordinates, colorArr = []){
let len = colorArr.length
let latLngToCoords = L.GeoJSON.latLngsToCoords(coordinates, 2, true, 8)
let coords = latLngToCoords[0][0]
let colors = []
let rateNum = coords.length / len
let proportion = 1 / rateNum
coords.forEach((item, index, arr) => {
let num = Math.floor(index / rateNum)
let newNum = num >= (len - 1) ? len - 1 : num
if (newNum >= len - 1) {
colors.push(colorArr[newNum])
} else {
// gradientColor方法只支持16进制颜色,如:#ff0000
let color = gradientColor(colorArr[newNum], colorArr[newNum + 1], proportion * ((index + 1) % rateNum))
colors.push(color)
}
})
console.log('colors', colors)
return {
coords,
colors
}
},
转完之后拿到数据和颜色数组就可以加到地图上了
let obj = this.getGeometryData(khGeo.features[0].geometry.coordinates, ['#5BAD01', '#ff0000', '#ffff00', '#ffffff'])
const polyline = L.polycolor(obj.coords, {
colors: obj.colors,
weight: 5
}).addTo(map);
附gradientColor方法:
/**
* @description 计算两个颜色的渐变色 指定比例的中间色
* @param {String} startColor 渐变色的起始色 hexcolor
* @param {String} endColor 渐变色的结束色 hexcolor
* @param {Float} proportion 从起始色到结束色的比例 比如从 #000000 到 #FFFFFF 渐变到 50% 时的颜色是 #888888 50%取值为 0.5
*/
function gradientColor(startColor, endColor, proportion = 1.0) {
// 此处调用了 自定义的 16 进制转换 10 进制的函数
const startColorDecimalisArray = transfeRgbHex(startColor);
const endColorDecimalisArray = transfeRgbHex(endColor);
// 两个颜色的差值数组
const rgbDifferenceArray = [];
//endColor 的 rgb 值 分别减掉 startColor 的 rgb 值并分别记录
for (let index = 0; index < startColorDecimalisArray.length; index++) {
rgbDifferenceArray.push(
endColorDecimalisArray[index] - startColorDecimalisArray[index]
);
}
let arr = [];
rgbDifferenceArray.forEach((item, index) => {
// startColor 的 rgb 值 分别加上对应比例的 rgb 差值 得到 结果色值的 rgb 数组
let num = startColorDecimalisArray[index] + Math.round(item * proportion) // 用proportion计算新的 rgb 色值
if (num < 0) {
num = 0
} else if (num > 255) {
num = 255
}
arr.push(num);
});
// 将 16 进制的 rgb 数组转换为 16进制表示法 hexColor 字符串
const resultHexColor = changeRgb(arr);
return resultHexColor;
}
window.gradientColor = gradientColor;
function changeRgb(arr){
let color = '#';
for(var i = 0; i < arr.length; i++){
var t = Number(arr[i]).toString(16)
if ( t.length === 1 ) {
t = "0" + t;
}
color += t;
}
return color;
}
/**
* @description 从 hex值中获取 rgb 颜色信息 并转换为 10 进制
* @param {String} hexcolor hex颜色值
* @return {Array} 一个包含 用十进制表示 rgba 值的数组[red, green, blue]
*/
function transfeRgbHex(hex) {
// 两位一组转换为 10 进制
var r = parseInt(hex.substr(1, 2), 16);
var g = parseInt(hex.substr(3, 2), 16);
var b = parseInt(hex.substr(5, 2), 16);
let rgbDecimalismArray = [r, g, b];
return rgbDecimalismArray;
}
// console.log(gradientColor("#FF00FF", "#FFFFFF", 0.5)); // 运行结果:#8080ff