echarts實現某個市3D地圖展示

應業務需求,以3D形式展示某個城市的地圖,並根據該城市下屬區域車輛的多少,動態變幻區域顏色
大概效果如下(顏色隨便給的,超醜 簡單記錄下吧)
在這裏插入圖片描述
以舟山市爲例:
1.生成舟山市的geojson文件
查詢鏈接:http://echarts.baidu.com/echarts2/doc/example/geoJson/china-main-city/522200.json
想要對應城市的geojson地圖數據文件,直接用對應城市的區劃代碼的前六位替換掉鏈接後面的區劃代碼即可(可參考https://blog.csdn.net/GRAY_KEY/article/details/80197527的博客)
2.引入對應的echarts.js和 echarts-gl.js(下載地址:https://www.echartsjs.com/zh/download.html
代碼如下:具體配置內容參考https://www.echartsjs.com/zh/option-gl.html#globe

  // 初始化圖表	
    var myChart = echarts.init(document.getElementById('main'));

    // JSON文件(地圖數據)路徑
    var uploadedDataURL = "json/zhoushan.json";

    var option = {};

    // 顯示加載動畫效果,可以在加載數據前手動調用該接口顯示加載動畫,在數據加載完成後調用 hideLoading 隱藏加載動畫。
    myChart.showLoading();

    // 引入JSON文件
    $.get(uploadedDataURL, function(geoJson) {

        // 註冊地圖名字(tongren)和數據(geoJson)
        echarts.registerMap('zhoushan', geoJson);

        // 隱藏動畫加載效果。
        myChart.hideLoading();

        // 圖表配置項		
        option = {

            title: { // 標題
                top: '5%',
                text: '舟山市3D地圖',
                subtext: '',
                x: 'center',
                textStyle: {
                    color: '#ccc'
                }
            },

            tooltip: { // 提示框
                trigger: 'item',
                formatter: function(params) {
                    return params.name;
                }
            },
            series: [{
                type: 'map3D', // 系列類型
                name: 'map3D', // 系列名稱
                map: 'zhoushan', // 地圖類型。echarts-gl 中使用的地圖類型同 geo 組件相同(ECharts 中提供了兩種格式的地圖數據,一種是可以直接 script 標籤引入的 js 文件,引入後會自動註冊地圖名字和數據。還有一種是 JSON 文件,需要通過 AJAX 異步加載後手動註冊。)
                // 環境貼圖,支持純顏色值,漸變色,全景貼圖的 url。默認爲 'auto',在配置有 light.ambientCubemap.texture 的時候會使用該紋理作爲環境貼圖。否則則不顯示環境貼圖。
                environment: new echarts.graphic.LinearGradient(0, 0, 0, 1, [{ // 配置爲垂直漸變的背景
                    offset: 0,
                    color: '#00aaff' // 天空顏色           
                }, {
                    offset: 0.7,
                    color: '#998866' // 地面顏色
                }, {
                    offset: 1,
                    color: '#998866' // 地面顏色
                }], false),

                label: { // 標籤的相關設置
                    show: true, // (地圖上的城市名稱)是否顯示標籤 [ default: false ]
                    //distance: 50,               // 標籤距離圖形的距離,在三維的散點圖中這個距離是屏幕空間的像素值,其它圖中這個距離是相對的三維距離
                    //formatter:,               // 標籤內容格式器
                    textStyle: { // 標籤的字體樣式
                        color: '#000', // 地圖初始化區域字體顏色
                        fontSize: 12, // 字體大小
                        opacity: 1, // 字體透明度
                        backgroundColor: 'rgba(0,23,11,0)' // 字體背景色
                    },
                },

                itemStyle: { // 三維地理座標系組件 中三維圖形的視覺屬性,包括顏色,透明度,描邊等。
                    color: 'rgba(95,158,160,0.5)', // 地圖板塊的顏色
                    opacity: 1, // 圖形的不透明度 [ default: 1 ]
                    borderWidth: 0.5, // (地圖板塊間的分隔線)圖形描邊的寬度。加上描邊後可以更清晰的區分每個區域   [ default: 0 ]
                    borderColor: '#000' // 圖形描邊的顏色。[ default: #333 ]
                },

                emphasis: { // 鼠標 hover 高亮時圖形和標籤的樣式 (當鼠標放上去時  label和itemStyle 的樣式) 
                    label: { // label高亮時的配置
                        show: true,
                        textStyle: {
                            color: '#fff', // 高亮時標籤顏色變爲 白色
                            fontSize: 15, // 高亮時標籤字體 變大
                        }
                    },
                    itemStyle: { // itemStyle高亮時的配置
                        areaColor: '#66ffff', // 高亮時地圖板塊顏色改變
                    }
                },

                groundPlane: { // 地面可以讓整個組件有個“擺放”的地方,從而使整個場景看起來更真實,更有模型感。
                    show: false, // 是否顯示地面。[ default: false ]
                    color: '#aaa' // 地面顏色。[ default: '#aaa' ]
                },
                light: { // 光照相關的設置。在 shading 爲 'color' 的時候無效。  光照的設置會影響到組件以及組件所在座標系上的所有圖表。合理的光照設置能夠讓整個場景的明暗變得更豐富,更有層次。
                    main: { // 場景主光源的設置,在 globe 組件中就是太陽光。
                        color: '#fff', //主光源的顏色。[ default: #fff ] 
                        intensity: 1.2, //主光源的強度。[ default: 1 ]
                        shadow: false, //主光源是否投射陰影。默認關閉。    開啓陰影可以給場景帶來更真實和有層次的光照效果。但是同時也會增加程序的運行開銷。
                        //shadowQuality: 'high',      // 陰影的質量。可選'low', 'medium', 'high', 'ultra' [ default: 'medium' ]
                        alpha: 55, // 主光源繞 x 軸,即上下旋轉的角度。配合 beta 控制光源的方向。[ default: 40 ]
                        beta: 10 // 主光源繞 y 軸,即左右旋轉的角度。[ default: 40 ]
                    },
                    ambient: { // 全局的環境光設置。
                        color: '#fff', // 環境光的顏色。[ default: #fff ]
                        intensity: 0.5 // 環境光的強度。[ default: 0.2 ]
                    }
                },

                viewControl: { // 用於鼠標的旋轉,縮放等視角控制。
                    projection: 'perspective', // 投影方式,默認爲透視投影'perspective',也支持設置爲正交投影'orthographic'。
                    autoRotate: false, // 是否開啓視角繞物體的自動旋轉查看。[ default: false ] 
                    autoRotateDirection: 'cw', // 物體自傳的方向。默認是 'cw' 也就是從上往下看是順時針方向,也可以取 'ccw',既從上往下看爲逆時針方向。
                    autoRotateSpeed: 10, // 物體自傳的速度。單位爲角度 / 秒,默認爲10 ,也就是36秒轉一圈。
                    autoRotateAfterStill: 3, // 在鼠標靜止操作後恢復自動旋轉的時間間隔。在開啓 autoRotate 後有效。[ default: 3 ]
                    damping: 0, // 鼠標進行旋轉,縮放等操作時的遲滯因子,在大於等於 1 的時候鼠標在停止操作後,視角仍會因爲一定的慣性繼續運動(旋轉和縮放)。[ default: 0.8 ]
                    rotateSensitivity: 1, // 旋轉操作的靈敏度,值越大越靈敏。支持使用數組分別設置橫向和縱向的旋轉靈敏度。默認爲1, 設置爲0後無法旋轉。	rotateSensitivity: [1, 0]——只能橫向旋轉; rotateSensitivity: [0, 1]——只能縱向旋轉。
                    zoomSensitivity: 2, // 縮放操作的靈敏度,值越大越靈敏。默認爲1,設置爲0後無法縮放。
                    panSensitivity: 1, // 平移操作的靈敏度,值越大越靈敏。默認爲1,設置爲0後無法平移。支持使用數組分別設置橫向和縱向的平移靈敏度
                    panMouseButton: 'left', // 平移操作使用的鼠標按鍵,支持:'left' 鼠標左鍵(默認);'middle' 鼠標中鍵 ;'right' 鼠標右鍵(注意:如果設置爲鼠標右鍵則會阻止默認的右鍵菜單。)
                    rotateMouseButton: 'left', // 旋轉操作使用的鼠標按鍵,支持:'left' 鼠標左鍵;'middle' 鼠標中鍵(默認);'right' 鼠標右鍵(注意:如果設置爲鼠標右鍵則會阻止默認的右鍵菜單。)
                    distance: 200, // [ default: 100 ] 默認視角距離主體的距離,對於 grid3D 和 geo3D 等其它組件來說是距離中心原點的距離,對於 globe 來說是距離地球表面的距離。在 projection 爲'perspective'的時候有效。
                    minDistance: 40, // [ default: 40 ] 視角通過鼠標控制能拉近到主體的最小距離。在 projection 爲'perspective'的時候有效。
                    maxDistance: 400, // [ default: 400 ] 視角通過鼠標控制能拉遠到主體的最大距離。在 projection 爲'perspective'的時候有效。
                    alpha: 40, // 視角繞 x 軸,即上下旋轉的角度。配合 beta 可以控制視角的方向。[ default: 40 ]
                    beta: 15, // 視角繞 y 軸,即左右旋轉的角度。[ default: 0 ]
                    minAlpha: -360, // 上下旋轉的最小 alpha 值。即視角能旋轉到達最上面的角度。[ default: 5 ]
                    maxAlpha: 360, // 上下旋轉的最大 alpha 值。即視角能旋轉到達最下面的角度。[ default: 90 ]
                    minBeta: -360, // 左右旋轉的最小 beta 值。即視角能旋轉到達最左的角度。[ default: -80 ]
                    maxBeta: 360, // 左右旋轉的最大 beta 值。即視角能旋轉到達最右的角度。[ default: 80 ]
                    center: [0, 0, 0], // 視角中心點,旋轉也會圍繞這個中心點旋轉,默認爲[0,0,0]。
                    animation: true, // 是否開啓動畫。[ default: true ]
                    animationDurationUpdate: 1000, // 過渡動畫的時長。[ default: 1000 ]
                    animationEasingUpdate: 'cubicInOut' // 過渡動畫的緩動效果。[ default: cubicInOut ]
                },
                boxWidth: 150,
                boxHeight: 150,
                regionHeight: 3,
                data: []
            }]
        };
        myChart.setOption(option);

    });

3.以上步驟走完後3D圖已經成型,接下來要完成顏色的改變
步驟如下:
根據給的初始色值,結尾色值,將色值劃分成n個階段,滿足某個階段(m)取某個值
當前要取的色值爲:(colorEnd-colorStart)/n*m+colorStart
由於rgb類型的色值更容易計算,要先將數值類型轉爲rgb在進行下面的處理
代碼如下:

// 參數:
    // startColor:開始顏色hex
    // endColor:結束顏色hex
    // step:幾個階級(幾步)
    */
    function gradientColor(startColor, endColor, step) {
        startRGB = this.colorRgb(startColor); //轉換爲rgb數組模式
        startR = startRGB[0];
        startG = startRGB[1];
        startB = startRGB[2];
        endRGB = this.colorRgb(endColor);
        endR = endRGB[0];
        endG = endRGB[1];
        endB = endRGB[2];
        sR = (endR - startR) / step; //總差值
        sG = (endG - startG) / step;
        sB = (endB - startB) / step;
        var colorArr = [];
        for (var i = 0; i < step; i++) {
            //計算每一步的hex值 
            var hex = this.colorHex('rgb(' + parseInt((sR * i + startR)) + ',' + parseInt((sG * i + startG)) + ',' + parseInt((sB * i + startB)) + ')');
            colorArr.push(hex);
        }
        return colorArr;
    }
    // 將hex表示方式轉換爲rgb表示方式(這裏返回rgb數組模式)
    gradientColor.prototype.colorRgb = function(sColor) {
        var reg = /^#([0-9a-fA-f]{3}|[0-9a-fA-f]{6})$/;
        var sColor = sColor.toLowerCase();
        if (sColor && reg.test(sColor)) {
            if (sColor.length === 4) {
                var sColorNew = "#";
                for (var i = 1; i < 4; i += 1) {
                    sColorNew += sColor.slice(i, i + 1).concat(sColor.slice(i, i + 1));
                }
                sColor = sColorNew;
            }
            //處理六位的顏色值
            var sColorChange = [];
            for (var i = 1; i < 7; i += 2) {
                sColorChange.push(parseInt("0x" + sColor.slice(i, i + 2)));
            }
            return sColorChange;
        } else {
            return sColor;
        }
    };
    // 將rgb表示方式轉換爲hex表示方式
    gradientColor.prototype.colorHex = function(rgb) {
        var _this = rgb;
        var reg = /^#([0-9a-fA-f]{3}|[0-9a-fA-f]{6})$/;
        if (/^(rgb|RGB)/.test(_this)) {
            var aColor = _this.replace(/(?:(|)|rgb|RGB)*/g, "").split(",");
            var strHex = "#";
            for (var i = 0; i < aColor.length; i++) {
                var hex = Number(aColor[i]).toString(16);
                hex = hex < 10 ? 0 + '' + hex : hex; // 保證每個rgb的值爲2位
                if (hex === "0") {
                    hex += hex;
                }
                strHex += hex;
            }
            if (strHex.length !== 7) {
                strHex = _this;
            }
            return strHex;
        } else if (reg.test(_this)) {
            var aNum = _this.replace(/#/, "").split("");
            if (aNum.length === 6) {
                return _this;
            } else if (aNum.length === 3) {
                var numHex = "#";
                for (var i = 0; i < aNum.length; i += 1) {
                    numHex += (aNum[i] + aNum[i]);
                }
                return numHex;
            }
        } else {
            return _this;
        }
    }
    // 將rgba表示方式轉爲hex
    gradientColor.prototype.colorRGBtoHex = function(color) {
        var rgb = color.split(',');
        var r = parseInt(rgb[0].split('(')[1]);
        var g = parseInt(rgb[1]);
        var b = parseInt(rgb[2].split(')')[0]);
        var hex = "#" + ((1 << 24) + (r << 16) + (g << 8) + b).toString(16).slice(1);
        return hex;
    }
    var colorArr = new gradientColor('#ffffff', '#000000', 100);

4.根據需要改變色值

function changeColor(arr) {
        var data = [];
        var obj = {};
        arr.map(function(item, key) {
            obj = { // 可對單個地圖區域進行設置
                name: item.name, // 所對應的地圖區域的名稱
                itemStyle: { // 單個區域的樣式設置
                    color: colorArr[item.value],
                    opacity: 1,
                    borderWidth: 0.4,
                    borderColor: colorArr[item.value]
                },
            };
            data.push(obj);
        })
        return data;
    }
    option.series[0].data = changeColor(arr);
    myChart.clear();
    myChart.setOption(option)

如下鏈接也可以自己研究下geojson的生成
http://geojson.io/#map=2/20.0/0.0

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章