这是部分js代码,代码里有一些标注,文章最后有相关问题,请耐心阅读,欢迎指导意见留言

function loadmap() {
**这段是风场数据处理调用的方法,可以暂时忽略**
    // https://github.com/Esri/wind-js/blob/master/windy.js#L41
    var createWindBuilder = function (uComp, vComp) {
        var uData = uComp.data,
            vData = vComp.data;
        return {
            header: uComp.header,        
            data: function (i) {
                return [uData[i], vData[i]];
            }
        }
    };

    var createBuilder = function (data) {
        var uComp = null,
            vComp = null,
            scalar = null;

        data.forEach(function (record) {
            switch (record.header.parameterCategory + "," + record.header.parameterNumber) {
                case "2,2":
                    uComp = record;
                    break;
                case "2,3":
                    vComp = record;
                    break;
                default:
                    scalar = record;
            }
        });

        return createWindBuilder(uComp, vComp);
    };

    var buildGrid = function (data, callback) {
        var builder = createBuilder(data);

        var header = builder.header;
        var Δλ = header.dx,//1        
        var ni = header.nx,//360
            nj = header.ny; //181, number of grid points W-E and N-S (e.g., 144 x 73)
        var date = new Date(header.refTime);
        date.setHours(date.getHours() + header.forecastTime);

        // Scan mode 0 assumed. Longitude increases from λ0, and latitude decreases from φ0.
        // http://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_table3-4.shtml
        var grid = [],
            p = 0;
        var isContinuous = Math.floor(ni * Δλ) >= 360;
        for (var j = 0; j < nj; j++) {
            var row = [];
            for (var i = 0; i < ni; i++, p++) {
                row[i] = builder.data(p);
            }
            if (isContinuous) {
                // For wrapped grids, duplicate first column as last column to simplify interpolation logic
                row.push(row[0]);
            }
            grid[j] = row;
        }
        callback(header, grid);
    };

** 1、首先初始化echarts实例,在想放地图的容器里**

    var dom = document.getElementById("map");
    var myChart = echarts.init(dom);
    var app = {};
**定义地图对象,用于获取echarts的百度地图对象**
    var map = null;//地图对象
    option = null;
    var data = [];
    var maxMag = 0;
    var minMag = Infinity;
    
** 3、这一步获取风场数据,将整理好的数据push到data数组里**

   $.getJSON('js/windData.json', function (windData) {
        buildGrid(windData, function (header, grid) {
            var p = 0;
            for (var j = 0; j < header.ny; j++) {//ny=181
                for (var i = 0; i < header.nx; i++) {//nx=360
                    var vx = grid[j][i][0];
                    var vy = grid[j][i][1];
                    var mag = Math.sqrt(vx * vx + vy * vy);
                    var lng = i / header.nx * 360;
                    if (lng >= 180) {
                        lng = 180 - lng;
                    }
                    // 数据是一个一维数组
                    // [ [经度, 维度,向量经度方向的值,向量维度方向的值] ]
                    data.push([
                        lng,
                        90 - j / header.ny * 180,
                        vx,
                        vy,
                        mag
                    ]);
                    maxMag = Math.max(mag, maxMag);
                    minMag = Math.min(mag, minMag);
                }
            }
        });//buildGrid结束
        
** 4、这里是风场开关,分别向series里添加风场数据和null数据控制风场的显隐,正常到这一步风场部分完成**

       //风场开关
       var flag = 0;//风场展示标志
       $(".map_right ul li:nth-child(2)").click(function () {
           if (flag == 0){
               myChart.setOption({
                   series: [{
                       data: data,
                   }]
               });
               flag = 1;
           }else {
               myChart.setOption({
                   series: [{
                       data: null,
                   }]
               });
               flag = 0;
           }
       })



   });//getjson结束
   
 ** 2、给echarts添加设置,正常情况下有1、2、两步就可以显示地图了**
 
            myChart.setOption({
                visualMap: {
                    left: 'right',        
                    dimension: 4,
                    inRange: {
                      
                        color: ['#313695', '#4575b4', '#74add1', '#abd9e9', '#e0f3f8', '#ffffbf', '#fee090', '#fdae61', '#f46d43', '#d73027', '#a50026']
                    },
                    realtime: false,
                    calculable: true,
                    textStyle: {
                        color: '#fff'
                    },
                },

                bmap: {
                    center: [114.511323, 37.077704],
                    zoom: 10,
                    roam: true   
**通常在这里设置地图样式,但是本文设置了自定义样式,所以在别处**           
                },
                
                series: [{
                    type: 'flowGL',
                    coordinateSystem: 'bmap',
 **风场数据在这里添加,但是加了开关,所以放在别处**
                   // data: data,
                    supersampling: 4,//采样更平滑,但是耗能大
                    particleType: 'line',
                    particleDensity: 40,//粒子密度,越大越密,实际粒子数为该值的平方
                    particleSpeed: 1,           
                    itemStyle: {
                        opacity: 1,//透明度              
                    },
                }]
            });

    if (option && typeof option === "object") {
        myChart.setOption(option, true);
    }

** 5、这里获取百度地图对象,用这个对象以后可以使用百度地图API操作地图,获取到对象就可以添加标注,设置监听了**
        map = myChart.getModel().getComponent('bmap').getBMap();
 **在这里添加的自定义地图样式,mj是本地的一个json数组**
        map.setMapStyleV2({styleJson: mj});
**给地图的标注设置了点击弹窗,但是被风场的层给遮住了,虽然能显示标注但是点击不到,所以将风场的层级降到比label标注的低,label标注的层级可查看控制台**
    //将风场层的显示优先级降到比BMapLabel的低 以不遮挡label的点击
    $(".BMap_mask").next().children().eq(3).find("div").css("z-index","-8000000");
    
**这是一个弹窗**
        //创建弹窗
        var infoWindow = new BMap.InfoWindow('', {offset: new BMap.Size(60, -30)});
        function openPopWindow(masker, el_id) {
            var els = $('#' + el_id).clone().show();
            if (els.size() > 0) {
                infoWindow.setContent(els[0]);
                map.openInfoWindow(infoWindow, masker.getPosition());
               els.find("div.bar[data-chart]").each(function () {
                    bar_map(this, $(this).data('args'));
                });
                els.find("div.pie[data-chart]").each(function () {
                    pie_map(this);
                });
            }
        }
        
**这是在地图加的label标注点**
        //网格员
        var pointGood = new BMap.Point(114.5113230000, 37.0777040000);
        var goodUp = {
            position: pointGood,    // 指定文本标注所在的地理位置
            offset: new BMap.Size(15, -30)    //设置文本偏移量
        }
        var labelGoodUp = new BMap.Label("", goodUp);  // 创建文本标注对象
        labelGoodUp.setStyle({
            cursor: 'pointer',
            width: "26px",
            height: "30px",
            fontSize: "12px",
            lineHeight: "26px",
            textAlign: "center",
            fontFamily: "微软雅黑",
            border: "none",
            backgroundColor: "none",
            borderRadius: "4px",
            backgroundImage: "url('img/map/map_man.png')",
            backgroundPosition: "center",
        });

        labelGoodUp.addEventListener("click", function () {   
            openPopWindow(this, 'pop_person');
        });

        map.addOverlay(labelGoodUp);

        var goodDown = {
            position: pointGood,    // 指定文本标注所在的地理位置
            offset: new BMap.Size(0, 4)    //设置文本偏移量
        }
        var labelGoodDown = new BMap.Label("网格员", goodDown);  // 创建文本标注对象
        labelGoodDown.setStyle({
            fontSize: "12px",
            width: "76px",
            backgroundColor: "#cdd3d7",
            textAlign: "center",
            height: "24px",
            color: "#000",
            lineHeight: "24px",
            fontFamily: "微软雅黑",
            border: "none",
            borderRadius: "4px",
        });

        map.addOverlay(labelGoodDown);
        
**这里监听zoom变化,实现当zoom小于一个数字之后,隐藏掉带“网格员”的label标注**
        //地图缩放 label展示变化
        var overlays = map.getOverlays();
        var length = overlays.length;
        var textOverlays = [];
        for (var i = 0; i < length; i++) {
            try{
 **这里能获取但是报错,报错会影响监听缩放,所以catch了一下**
                if (overlays[i].getOffset().width == 0){//获取展示文字的label
                    textOverlays.push(overlays[i]);
                }
            }
            catch (e) 
            }
        }
        var textLength = textOverlays.length;
        var hide = false;
        if(map.getZoom() < 15){
            for (var i = 0; i < textLength; i++) {
                textOverlays[i].hide();
            }
            hide = true;
        }
            map.addEventListener('zoomend', function () {
              if (map.getZoom() < 15 && hide != true) {
                  for (var i = 0; i < textLength; i++) {
                      textOverlays[i].hide();
                  }
                  hide = true;
              } else if (map.getZoom() >= 15 && hide == true) {
                  for (var i = 0; i < textLength; i++) {
                      textOverlays[i].show();
                  }
                  hide = false;
              }

          })
}

echarts官网风场矢量位置:
https://www.echartsjs.com/examples/zh/editor.html?c=global-wind-visualization-2&gl=1 以上代码是在百度地图上通过echarts风场建立一个风场层,并且仍可以使用百度地图api的方法建立标注,设置监听等。

1、该引入的文件引入之后,初始化echarts实例,设置option显示地图,获得风场数据进行添加,获得百度地图对象进行其他操作,在上面代码里进行了步骤标注

2、关于百度地图map对象的获取**

百度发现

u风场 v风场 python 角度_echarts风场


这个是回调函数,最后执行,在官网代码里echarts的setoption放在这里面,是最后执行,所以在这之外获取不到map对象。注意在setoption中设置了bmap之后才能获取map对象。

3、关于风场数据获取:

u风场 v风场 python 角度_u风场 v风场 python 角度_02


这是echarts官网通过Ajax异步加载文件获取数据的方法,他的数据存在gfs.json文件中,控制台搜索ROOT_PATH得到对应路径如下

u风场 v风场 python 角度_百度地图_03


通过拼接后得到数据路径为:https://www.echartsjs.com/examples/data-gl/asset/data/gfs.json,

在浏览器输入该路径得到数据如下,可全选复制粘贴到json文件中,这是官网使用的风向数据

u风场 v风场 python 角度_echarts风场_04


该数据内有两份格式一样的json数据,都包含header和data,header内是一些标志信息,data内为风场数据。以下是官网处理数据的代码

u风场 v风场 python 角度_echarts风场_05


(不止这些,还有调用的方法,没有在这里截图)通过以上数据处理方法大致得到以下信息,数据文件的

两份数据一份是经度方向上的速度,一份是纬度方向上的速度。每份数据的排列是按照北纬90向南纬90,然后分别每个纬度上的0经度到360经度的点上的速度,每份是181*360=65160个点位。

通过以上方法将数据处理成格式为二维数组的数据 data[[经度,纬度,经度方向的速度,纬度方向的速度],[],[],[],[]]。此处还计算了以下合速度mag即vx平方加vy平方开根号,不知道有没有用到,因为官网给出的数据格式是这种

u风场 v风场 python 角度_数据_06