openlayers、cesium 使用散列点数据绘制canvas图像_liuqing0.0的博客
作者:互联网
前言:我并不知道后端处理的是什么后缀的文件。我这里需要使用的只有一些属性值。形状如下。
最终成品图如下:
如你所见最终的结果是一个扇形图。这是由数据本身决定的。
在进入正题之前,先说明这图着色的具体的原理。先上代码
class ColorRangeMaker {
option = {};
constructor(option) {
let vRange = option.value[1] - option.value[0];
if (option.color.length == 2) {//仅有两个颜色
let rA = (option.color[1][0] - option.color[0][0]) / vRange;
let gA = (option.color[1][1] - option.color[0][1]) / vRange;
let bA = (option.color[1][2] - option.color[0][2]) / vRange;
this.option = { vRange, rA, gA, bA, option };
} else {//两个以上颜色
const makers = [];
let vA = vRange / (option.color.length - 1);
for (let i = 1; i < option.color.length; i++) {
const maker = new ColorRangeMaker({
color: [option.color[i - 1], option.color[i]],
value: [option.value[0] + vA * (i - 1),
option.value[0] + vA * i]
});
makers.push(maker);
}
this.option = { makers, vA, option };
}
}
make(value) {
const { makers, vRange, rA, gA, bA, vA, option } = this.option;
if (value < option.value[0]) {
return option.color[0];
} else if (value > option.value[option.value.length - 1]) {
return option.color[option.color.length - 1];
} else {
if (option.color.length == 2) {//仅有两个颜色
let color = option.color[0].map(a => a);
let vATmp = value - option.value[0];
color[0] += parseInt(rA * vATmp);
color[1] += parseInt(gA * vATmp);
color[2] += parseInt(bA * vATmp);
return color.join(',');
} else {
for (let i = 1; i < option.color.length; i++) {
if (value <= option.value[0] + vA * i) {
return makers[i - 1].make(value);
}
}
}
}
}
}
export default ColorRangeMaker;
这个我忘记是从哪里找的了。。原谅我懒得翻出来贴上原地址。
简要说明一下具体的原理: 根据最大最小值作为坐标轴的区间,用颜色数组的长度来进行分段。通过查看当前值在哪两个分段值内,通过比例计算当前值得RGB值。
const cm = new ColorRangeMaker({
color: colors,
value: [Number(minData), Number(maxData)],
})
cm.make(value); // [111,111,111] => '111,111,111'
canvas 绘制
createFanChart: function () {
let header = testdata.header
let data = testdata.data
let valSize = header.valSize
let latMin = header.latMin
let lonMin = header.lonMin
let latMax = header.latMax
let lonMax = header.lonMax
// 这里为什么加 1 是一个根据色块的渲染做的判断。如果不明白可以往下看 fillRect 的参数
let width = header.lonMax - header.lonMin + 1
let height = header.latMax - header.latMin + 1
let canvas = document.createElement('canvas')
let ctx = canvas.getContext('2d')
// 这里 乘10的原因在于 需要 放大 10 倍去绘制,可以让锯齿明显的减少。
canvas.height = height * 10
canvas.width = width * 10
//颜色
let colors = []
// colors 应该是这种形式的 [ [0,0,0] , [ 111,111,111] ];
let [minData, maxData] = [header.valMin, header.valMax]
const cm = new ColorRangeMaker({
color: colors,
value: [Number(minData), Number(maxData)],
})
// 绘制 散列点 到canvas上
for (let i = 0; i < valSize; i++) {
ctx.fillStyle = 'rgb(' + cm.make(data.val[i]) + ')'
// 这里 x 位置上 减去最小经度的原因是因为: 这个值是负的。
// 所以理论上来说 这段代码 只包含了这种 情况:
// lonMin = - ? , lonMax = + ? , latMax = + , latMin = +
// 由于目前只是写了demo 出来 这部分转换还是没有去做的。望知晓。
// 我认为在上面做处理会更好。 在这里 应该是有一个统一的公式的。
ctx.fillRect(
(data.lon[i] - lonMin) * 10,
(latMax - data.lat[i]) * 10,
10,
10
)
}
// 剪切 canvas 图片.
console.log(canvas.toDataURL())
return canvas.toDataURL()
},
闲聊
这个时候肯定会有老哥出来说了,你这啥玩意 ,没有openlayers为啥标题还写openlayers 。。反正我需求是根据地形的数据画扇形图,至于用openlayers 或者cesium 这些 框架 咋贴上去,我只能说,多的是博客教你。
本文转自 https://blog.csdn.net/q1025387665a/article/details/122156120?spm=1001.2014.3001.5502,如有侵权,请联系删除。
标签:散列点,canvas,option,color,value,header,let,openlayers 来源: https://www.cnblogs.com/hustshu/p/16283080.html