openlayers、cesium 使用散列点数据绘制canvas图像

前言:我并不知道后端处理的是什么后缀的文件。我这里需要使用的只有一些属性值。形状如下。
在这里插入图片描述
最终成品图如下:
在这里插入图片描述
如你所见最终的结果是一个扇形图。这是由数据本身决定的。

在进入正题之前,先说明这图着色的具体的原理。先上代码

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 这些 框架 咋贴上去,我只能说,多的是博客教你。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
OpenLayers是一个开源的JavaScript库,用于在Web浏览器显示交互式地图。OpenLayers可以加载各种类型的地图数据,包括矢量数据、栅格数据、WMS服务等。下面是实现可视化的步骤: 1. 准备气象战数据,可以是CSV、JSON等格式的文件。 2. 在HTML页面添加OpenLayers的引用: ``` <script src="https://cdn.jsdelivr.net/npm/ol@6.4.3/dist/ol.js"></script> <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/ol@6.4.3/dist/ol.css" /> ``` 3. 创建一个地图容器: ``` <div id="map" style="width: 100%; height: 600px;"></div> ``` 4. 创建一个OpenLayers地图对象: ``` var map = new ol.Map({ target: 'map', layers: [ new ol.layer.Tile({ source: new ol.source.OSM() }) ], view: new ol.View({ center: ol.proj.fromLonLat([120, 30]), zoom: 8 }) }); ``` 5. 加载气象战数据: ``` var features = []; // 读取CSV文件数据 d3.csv("data.csv", function(data) { data.forEach(function(d) { // 将数据转换为OpenLayers要求的格式 var feature = new ol.Feature({ geometry: new ol.geom.Point(ol.proj.fromLonLat([+d.lng, +d.lat])), name: d.name, value: +d.value }); features.push(feature); }); // 创建矢量图层 var vectorLayer = new ol.layer.Vector({ source: new ol.source.Vector({ features: features }), style: function(feature) { // 根据value的值设置的颜色和大小 var color = 'rgba(255, 0, 0, 0.5)'; var size = 10; if (feature.get('value') > 10) { color = 'rgba(0, 255, 0, 0.5)'; size = 20; } return new ol.style.Style({ image: new ol.style.Circle({ radius: size, fill: new ol.style.Fill({ color: color }) }) }); } }); // 将矢量图层添加到地图 map.addLayer(vectorLayer); }); ``` 6. 根据需要设置地图的样式和交互功能。 以上就是使用OpenLayers加载气象战数据实现可视化的步骤。需要注意的是,代码使用了d3.csv方法读取CSV文件数据,因此需要在HTML页面添加d3.js的引用。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值