数据可视化

SuperMap iClient for MapboxGL 支持可视化包含:

1.热力图

2.高效率点图层

3.ECharts

4.EChartsGL

5.DeckGL

6.MapV

7.Threejs

  • 热力图

应用场景:由于热力图的衰减是像素级别的,视觉效果方面极佳,但不能与具体数据进行一一对应,只能表示权重之间的差别,所以可以用于一些对精度要求不高而需要重点突出权重渐变的行业,如可以制作气象温度对比动态效果图、地震区域的震点强弱图等。

示例代码:

// 定义热力点数量,加热力半径
heatMapLayer = new mapboxgl.supermap.HeatMapLayer(
    "heatMap",
    {
        "map": map,
        "id": "heatmap",
        "radius": 45,
        //featureWeight指定以哪个属性值为热力权重值创建热力图
        "featureWeight": "value",
    }
);

// 构造热力中心点
function createHeatPoints() {
    clearHeatPoints();
    let heatPoints = [];
    let num = 200;
    let radius = 50;
    let unit = "px";
    heatMapLayer.useGeoUnit = true;
    heatMapLayer.radius = radius;

    let features = [];
    for (let i = 0; i < num; i++) {
        features[i] =
        {
            "type": "feature",
            "geometry": {
                "type": "Point",
                "coordinates": [
                    Math.random() * 360 - 180,
                    Math.random() * 160 - 80]
            },
            "properties": {
                "value": Math.random() * 9,
            }
        };
    }

    let heatPoints = {
        "type": "FeatureCollection",
        "features": features
    };

    heatMapLayer.addFeatures(heatPoints);
    map.addLayer(heatMapLayer);
}

运行效果如下:

  • 高效率点图层

高效率点图层(graphicLayer),主要是针对前端大数据量的点渲染。graphicLayer 支持选取对象事件。(需要引入PapaParse,deck.gl,dat-gui)

$.get('../data/nyc-taxi.csv', function (csvstr) {
    // 读取文件中的数据
    let result = Papa.parse(csvstr, {skipEmptyLines: true, header: true});
    addLayer(result.data);
});
// 定义样式相关属性
function addLayer(points) {
    let graphics = [];
    for (let i = 0; i < points.length; i++) {

        let lngLat = {
            lng: parseFloat(points[i].lng),
            lat: parseFloat(points[i].lat)
        };
        /**
         * 可以单独给要素设置颜色和半径:
         * new mapboxgl.supermap.Graphic(lngLat,{
         *      color:[255,0,0],
         *      radius:40
         * });
         */
        graphics.push(new mapboxgl.supermap.Graphic(lngLat));
    }

    let graphicStyle = {
        color: [0, 255, 128],
        radius: 10
    };
    // 绘制对象,并添加到图层上
    graphicLayer = new mapboxgl.supermap.GraphicLayer("graphic", {
        graphics: graphics,
        radius: graphicStyle.radius,
        color: graphicStyle.color,
        highlightColor: [255, 0, 0, 255],
    });
    // 将画出来的点渲染到地图上
    map.addLayer(graphicLayer);
}

运行效果如下:

  • ECharts

ECharts 提供了常规的折线图、柱状图、散点图、饼图、K线图,用于统计的盒形图,用于地理数据可视化的地图、热力图、线图,用于关系数据可视化的关系图、treemap、旭日图,多维数据可视化的平行坐标,还有用于 BI 的漏斗图,仪表盘,并且支持图与图之间的混搭。(需要引入ECharts,echartsLayer)

下面以长春市公交路特效图为例,将公交路线的数据进行可视化的展示:

let uploadedDataURL = "../data/changchunBus.json";
$.get(uploadedDataURL, function (data) {
    option = {
        animation: false,
        GLMap: {
            roam: true
        },
        coordinateSystem: 'GLMap',
        geo: {
            map: 'GLMap',
        },

        series: [{
            type: 'lines',
            polyline: true,
            data: data,
            silent: true,
            lineStyle: {
                normal: {
                    opacity: 0.2,
                    width: 1
                }
            },
            progressiveThreshold: 500,
            progressive: 100,
        }, {

            type: 'lines',
            coordinateSystem: 'GLMap',
            polyline: true,
            data: data,
            lineStyle: {
                normal: {
                    width: 0.2
                }
            },
            effect: {
                constantSpeed: 40,
                show: true,
                trailLength: 0.02,
                symbolSize: 2
            },
        }]
    };
    let echartslayer = new EchartsLayer(map);
    echartslayer.chart.setOption(option);
});

运行效果如下:

  • EChartsGL

ECharts GL 是 ECharts 的 WebGL 扩展,其中提供了三维散点图,飞线图,柱状图,曲面图,地球等多种三维可视化方式。并且增加 scatterGL,graphGL 系列类型用于二维的散点图,关系图的加速绘制和布局。(需要引入ECharts,echartsLayer,ECharts-GL)

下面以全球风能为例,将风能数据进行可视化的展示:

map.on('load', function () {
    $.getJSON('../data/globalWindData.json', function (windData) {
    let data = [];
    let p = 0;
    let maxMag = 0;
    let minMag = Infinity;
    for (let j = 0; j < windData.ny; j++) {
        for (let i = 0; i < windData.nx; i++, p++) {
            let vx = windData.data[p][0];
            let vy = windData.data[p][1];
            let mag = Math.sqrt(vx * vx + vy * vy);
            // 数据是一个一维数组
            // [ [经度, 纬度,向量经度方向的值,向量纬度方向的值] ]
            data.push([
                i / windData.nx * 360 - 180,
                j / windData.ny * 180 - 90,
                vx,
                vy,
                mag
            ]);
            maxMag = Math.max(mag, maxMag);
            minMag = Math.min(mag, minMag);
        }
    }

    let echartslayer = new EchartsLayer(map);
    echartslayer.chart.setOption({
        GLMap: {
            roam: true,
        },
        geo: {
            map: "GLMap"
        },
        visualMap: {
            left: 'right',
            min: minMag,
            max: maxMag,
            dimension: 4,
            inRange: {
                color: ['#313695', '#4575b4', '#74add1', '#abd9e9', '#e0f3f8', '#ffffbf', '#fee090', '#fdae61', '#f46d43', '#d73027', '#a50026']
            },
            realtime: false,
            calculable: true,
            textStyle: {
                color: '#fff'
            }
        },
        series: [{
            type: 'flowGL',
            coordinateSystem: 'GLMap',
            data: data,
            particleDensity: 512,
            particleSpeed: 2,
            particleSize: 1,
            gridWidth: windData.nx,
            gridHeight: windData.ny,
            itemStyle: {
                opacity: 0.7
            }
         }]
     });
    });
});

运行效果如下:

  • DeckGL

DeckGL 是由 Uber 开发并开源出来的基于 WebGL 的大数据量可视化框架。它具有提供不同类型可视化图层,GPU渲染的高性能,React 和 Mapbox GL 集成,结合地理信息数据(GPS)的特点。(需要引入deck.gl)

对数据进行蜂巢图层展示:

$.get('../data/deck.gl/sf-bike-parking.json', function (features) {
    addLayer(features);
});
function addLayer(features) {
    deckglLayer = new mapboxgl.supermap.DeckglLayer("hexagon-layer", {
        data: features,
        props: {
             extruded: true, // 是否拉伸要素,默认为false
             radius: 200, // 六边形半径值,默认为1000
             elevationScale: 4, // 高程乘数
             coverage: 0.8 // 六边形半径乘数,介于0 - 1之间。六边形的最终半径通过覆盖半径计算。
            // 还可配置的参数:
            // colorRange 色带,
            // 默认为 [[255,255,178,255],[254,217,118,255],[254,178,76,255],[253,141,60,255],[240,59,32,255],[189,0,38,255]]
        },
        callback: {
            getPosition: d => d.COORDINATES,
        }
    });
    map.addLayer(deckglLayer);
}

运行效果如下:

  • MapV

MapV 是一款地理信息可视化开源库,可以用来展示大量地理信息数据,点、线、面的数据,每种数据也有不同的展示类型,如直接打点、热力图、网格、聚合等方式展示数据。MapV 可展示大量的点数据,形式可以为热力图、网格、蜂窝状、点聚合、按颜色区间、按半径大小等。可展示大量的线数据,如普通画线、高亮叠加、热力线数据展示等方式,还有各种动画效果,适合用于呈现大量轨迹的场景。也可展示大量的自定义面数据,按颜色区间来展示,行政区域也是其中一种应用场景,可直接使用。(需要引入MapV)

SuperMap iClient for MapboxGL 提供了对使用 MapV 可视化效果图层的支持,接口为:mapboxgl.supermap.MapvLayer(dataSet, options)

下面以 MapV 强边界图为例,将数据进行可视化的展示:

let randomCount = 500;
let node_data = {
    "0": {"x": 108.154518, "y": 36.643346},
    "1": {"x": 121.485124, "y": 31.235317},
};
let edge_data = [
    {"source": "1", "target": "0"}
];
let citys = ["北京", "天津", "上海", "重庆", "石家庄", "太原", "呼和浩特", "哈尔滨", "长春", "沈阳", "济南", "南京", "合肥", "杭州", "南昌", "福州", "郑州", "武汉", "长沙", "广州", "南宁", "西安", "银川", "兰州", "西宁", "乌鲁木齐", "成都", "贵阳", "昆明", "拉萨", "海口"];

// 构造数据
for (let i = 1; i < randomCount; i++) {
    let cityCenter = mapv.utilCityCenter.getCenterByCityName(citys[parseInt(Math.random() * citys.length)]);
    node_data[i] = {
        x: cityCenter.lng - 5 + Math.random() * 10,
        y: cityCenter.lat - 5 + Math.random() * 10,
    };
    edge_data.push(
        {"source": ~~(i * Math.random()), "target": '0'}
    );
}

let fbundling = mapv.utilForceEdgeBundling()
    .nodes(node_data)
    .edges(edge_data);

let results = fbundling();

let data = [];
let timeData = [];

for (let i = 0; i < results.length; i++) {
    let line = results[i];
    let coordinates = [];
    for (let j = 0; j < line.length; j++) {
        coordinates.push([line[j].x, line[j].y]);
        timeData.push({
            geometry: {
                type: 'Point',
                coordinates: [line[j].x, line[j].y]
            },
            count: 1,
            time: j
        });
    }

    data.push({
        geometry: {
            type: 'LineString',
            coordinates: transformCoords(coordinates)
        }
    });

    function transformCoords(coordinates) {
        let coords = [];
        coordinates.map(function (coordinate) {
            coords.push(coordinate);
        });
        return coords;
    }
}

let dataSet = new mapv.DataSet(data);

let options = {
    strokeStyle: 'rgba(55, 50, 250, 0.3)',
    globalCompositeOperation: 'lighter',
    shadowColor: 'rgba(55, 50, 250, 0.5)',
    shadowBlur: 10,
    lineWidth: 1.0,
    draw: 'simple'
};

// mapboxgl.supermap.MapvLayer 构造函数的第一个 map 参数将在下个版本遗弃
let mapVLinelayer = new mapboxgl.supermap.MapvLayer("", dataSet, options);
map.addLayer(mapVLinelayer);

// 创建MapV图层
let dataSet = new mapv.DataSet(timeData);

let options = {
    fillStyle: 'rgba(255, 250, 250, 0.9)',
    globalCompositeOperation: 'lighter',
    size: 1.5,
    animation: {
        type: 'time',
        stepsRange: {
            start: 0,
            end: 100
        },
        trails: 1,
        duration: 5
    },
    draw: 'simple'
};

// mapboxgl.supermap.MapvLayer 构造函数的第一个 map 参数将在下个版本遗弃
let mapVAnimationLinelayer = new mapboxgl.supermap.MapvLayer("", dataSet, options);
map.addLayer(mapVAnimationLinelayer);

运行效果如下:

  • Threejs

Three.js 是一款开源的主流 3D 绘图 JS 引擎(需要引入Three.js,GLTFLoader)

SuperMap iClient for MapboxGL 提供了对使用 Three.js 可视化效果图层的支持,接口为:mapboxgl.supermap.ThreeLayer('three')

function loaderModels() {
    let loader = new THREE.GLTFLoader();
    // 加载gltf格式数据
    loader.load('./js/airplane/airplane.glb', function (gltf) {
        let scene = gltf.scene;
        scene.rotation.x = -Math.PI / 2;
        scene.rotation.y = Math.PI / 2;
        scene.scale.multiplyScalar(150);

        addThreeLayer(scene);
    });
}

function addThreeLayer(meshes) {
    threeLayer = new mapboxgl.supermap.ThreeLayer('three');
    threeLayer.on("initialized", render);
    threeLayer.addTo(map);

    function render() {
        let renderer = threeLayer.getThreeRenderer(),
            scene = threeLayer.getScene(),
            camera = threeLayer.getCamera();

        this.light = new THREE.PointLight(0xaaaaaa, 0.5);
        this.light.position.copy(camera.position);
        scene.add(this.light);
        scene.add(new THREE.AmbientLight(0xffffff));
        threeLayer.setPosition(meshes, position);
        // 设置飞行高度
        meshes.translateY(5000);
        scene.add(meshes);

        (function animate() {
            requestAnimationFrame(animate);
            meshes.position.y -= 60;
            let center = map.getCenter().toArray();
            center[1] += 0.00008;
            map.setCenter(center);
            renderer.render(scene, camera);
        })()
    }

    // 均匀光照,与相机位置同步
    threeLayer.on("render", function () {
        threeLayer.light.position.copy(threeLayer.renderer.camera.position);
    });
}

运行效果如下:

Copyright © lujiannb@qq.com 2021 all right reserved,powered by Gitbook该文章修订时间: 2024-06-06 11:32:07

results matching ""

    No results matching ""