一、编写EchartsLayer类实现注入到window对象,实现类如下:

import * as Cesium from 'cesium/Cesium'
import * as echarts from 'echarts'
!(function () {
  function EchartsLayer(viewer) {
    this._viewer = viewer;
    registerMap(this);
    createChart(this);
    resize(this);
  }

  Object.defineProperties(EchartsLayer.prototype, {
    chart: {
      get: function () {
        return this._chart;
      }
    }
  })

  function registerMap(layer) {
    if (!Cesium.defined(echarts)) {
      throw new Cesium.DeveloperError("echarts is undefined.");
    }
    echarts.registerCoordinateSystem("GLMap", getCoordinateSystem(layer._viewer)),
      echarts.registerAction({
        type: "GLMapRoam",
        event: "GLMapRoam",
        update: "updateLayout"
      }, function (t, e) {
      }),
      echarts.extendComponentModel({
        type: "GLMap",
        defaultOption: {roam: !1}
      });
    echarts.extendComponentView({
      type: "GLMap",
      init: function (t, e) {
        this.api = e;
        layer._viewer.scene.postRender.addEventListener(this.moveHandler, this)
      },
      moveHandler: function (t, e) {
        this.api.dispatchAction({
          type: "GLMapRoam"
        });
      },
      render: function (t, e, i) {
      },
      dispose: function (t) {
        layer._viewer.scene.postRender.removeEventListener(this.moveHandler, this)
      }
    });
  }

  function createChart(layer) {
    var scene = layer._viewer.scene;
    scene.canvas.setAttribute("tabIndex", 0);
    var ele = document.createElement('div');
    ele.style.position = "absolute";
    ele.style.top = "0px";
    ele.style.left = "0px";
    ele.style.width = scene.canvas.width + "px";
    ele.style.height = scene.canvas.height + "px";
    ele.style.pointerEvents = "none";
    ele.setAttribute("id", "echarts");
    ele.setAttribute("class", "echartMap");
    layer._viewer.container.appendChild(ele);
    layer._echartsContainer = ele;
    layer._chart = echarts.init(ele);
  }

  function resize(layer) {
    window.onresize = function () {
      var scene = layer._viewer.scene;
      layer._echartsContainer.style.width = scene.canvas.style.width + "px";
      layer._echartsContainer.style.height = scene.canvas.style.height + "px";
      layer._chart.resize();
    }
  }

  EchartsLayer.prototype.isDestroyed = function () {
    return false;
  };

  EchartsLayer.prototype.destroy = function () {
    if (this._echartsContainer) {
      this._viewer.container.removeChild(this._echartsContainer);
      this._echartsContainer = undefined;
    }
    if (this._chart) {
      this._chart.dispose();
      this._chart = undefined;
    }
    Cesium.destroyObject(this);
  }

  function getCoordinateSystem(viewer) {
    function GLMapCoordSys(api) {
      this.dimensions = ['lng', 'lat'];
      this._mapOffset = [0, 0];
      this._api = api;
      this._viewer = viewer;
      this._occluder = new Cesium.EllipsoidalOccluder(this._viewer.scene.globe.ellipsoid, this._viewer.scene.camera.position);
    }

    GLMapCoordSys.prototype.dimensions = ['lng', 'lat']

    GLMapCoordSys.prototype.setMapOffset = function (mapOffset) {
      this._mapOffset = mapOffset;
    };

    GLMapCoordSys.prototype.dataToPoint = function (data) {
      var e = [0, 0],
        i = Cesium.Cartesian3.fromDegrees(data[0], data[1]);
      if (!i) return e;
      this._occluder.cameraPosition = this._viewer.scene.camera.position;
      if(!this._occluder.isPointVisible(i)) {
        return [];
      };
      var n = viewer.scene.cartesianToCanvasCoordinates(i);
      if (!n) return e;
      return (Cesium.Cartesian3.angleBetween(viewer.scene.camera.position, i) < Cesium.Math.toRadians(75))
        ? [n.x - this._mapOffset[0], n.y - this._mapOffset[1]] : e;
    }

    GLMapCoordSys.prototype.pointToData = function (pt) {
      var mapOffset = this._mapOffset;
      var cart = viewer.scene.pickPosition(
        new Cartesian2(pt[0] + mapOffset[0], pt[1] + mapOffset[1]), new Cesium.Cartesian3()
      );
      var carto = Cesium.Cartographic.fromCartesian(cart);
      return [Cesium.Math.toDegrees(carto.longitude), Cesium.Math.toDegrees(carto.latitude)];
    }

    GLMapCoordSys.prototype.getViewRect = function () {
      var api = this._api
      return new echarts.graphic.BoundingRect(0, 0, api.getWidth(), api.getHeight())
    }

    GLMapCoordSys.prototype.getRoamTransform = function () {
      return echarts.matrix.create();
    }

    GLMapCoordSys.dimensions = GLMapCoordSys.prototype.dimensions

    GLMapCoordSys.create = function (ecModel, api) {
      var coordSys;
      ecModel.eachComponent('GLMap', function (GLMapModel) {
        coordSys = new GLMapCoordSys(api);
        coordSys.setMapOffset(GLMapModel.__mapOffset || [0, 0]);
        GLMapModel.coordinateSystem = coordSys;
      })
      ecModel.eachSeries(function (seriesModel) {
        if (seriesModel.get('coordinateSystem') === 'GLMap') {
          seriesModel.coordinateSystem = coordSys;
        }
      })
    }
    return GLMapCoordSys;
  }

  window.EchartsLayer = EchartsLayer;
})();

二、编写调用工具类

/***
 * echarts图层通用工具
 * date:2022-04-15
 * author:zdh
 * @type {EchartsLayerUtil}
 */
import './EchartsLayer'
import * as Cesium from 'cesium/Cesium'
let EchartsLayerUtil = (function () {
  function EchartsLayerUtil (ZJNCesium) {
    this.ZJNCesium = ZJNCesium
    this.transferLayer = null
  }
  EchartsLayerUtil.prototype.createTransferLayer = function (data,idField,labelField){
    let geoCoordMap = data.geoCoordMap;
    let convertData = function (data) {
      let res = [];
      for (let i = 0; i < data.length; i++) {
        let dataItem = data[i];
        let fromCoord = [parseFloat(geoCoordMap[dataItem[0][idField]][0]),parseFloat(geoCoordMap[dataItem[0][idField]][1])];
        let toCoord = [parseFloat(geoCoordMap[dataItem[1][idField]][0]),parseFloat(geoCoordMap[dataItem[1][idField]][1])];
        if (fromCoord && toCoord) {
          res.push({
            fromName: dataItem[0][idField],
            toName: dataItem[1][idField],
            coords: [fromCoord, toCoord],
            value: 3,
          });
        }
      }
      return res;
    }
    let series = [];
    data.resultData.forEach(function (item, i) {
      series.push(
        {
          coordinateSystem: 'GLMap',
          type: "effectScatter",
          symbolSize: 20,
          hoverAnimation: true,
          itemStyle: {
            color: "rgba(60,53,212,1)",
            borderColor: "rgba(60,53,212,0.4)",
            borderWidth: 10
          },
          data: [
            {
              value: [parseFloat(geoCoordMap[item[0][0][idField]][0]),parseFloat(geoCoordMap[item[0][0][idField]][1])],
              itemStyle: {
                normal: {
                  color: '#df27ba'
                }
              }
            }
          ],
          label: {
            normal: {
              show: true,
              position: 'right', //显示位置
              offset: [5, 0], //偏移设置
              formatter: function (params) {
                //圆环显示文字
                return item[0][0][labelField];
              },
              fontWeight: 8,
              fontSize: 20,
            },
          }

        },
        {
          name: 'Top10',
          type: 'lines',
          coordinateSystem: 'GLMap',
          zlevel: 2,
          symbol: ['none','circle'],
          emphasis: {
            lineStyle: {
              color: 'rgb(255,255,108)',
              width: 6,
            },
          },
          tooltip: {
            formatter: '{b}',
          },
          animation: false,
          symbolSize: 10,
          effect: {
            show: true,
            period: 4, //箭头指向速度,值越小速度越快
            trailLength: 0.02, //特效尾迹长度[0,1]值越大,尾迹越长重
            symbol: 'arrow', //箭头图标
            symbolSize: 8, //图标大小
          },
          lineStyle: {
            normal: {
              color:'#eee',
              width: 1, //尾迹线条宽度
              opacity: 1, //尾迹线条透明度
              curveness: 0.3, //尾迹线条曲直度
            },
          },
          data: convertData(item)
        }
      )
    })
    this.transferLayer = new EchartsLayer(this.ZJNCesium.viewer)
    let option = {
      // title: {
      //     text: 'ArcGIS API for Javascript4.10扩展Echarts4之模拟迁徙',
      //     subtext: 'Data from Echart社区,Develop By YANG',
      //     left: 'center',
      //     textStyle: {
      //         color: '#fff'
      //     }
      // },
      animation: false,
      GLMap: {},
      tooltip: {
        trigger: 'item'
      },
      series: series
    };
    this.transferLayer.chart.setOption(option)

    let handler = new Cesium.ScreenSpaceEventHandler(this.ZJNCesium.viewer.scene.canvas);
    handler.setInputAction(function (e) {
      let pos = this.ZJNCesium.viewer.scene.pickPosition(e.position);
      console.log(pos);
    }, Cesium.ScreenSpaceEventType.LEFT_CLICK);
  }
  return EchartsLayerUtil
}())
export {EchartsLayerUtil}

三、测试数据整理

{
  "geoCoordMap": {
    "cbbb669db45c4fe19ce9074bfb4cd1e8": [
      114.696074,
      35.898948
    ],
    "e3fb0b7892f74cff96f008567194d947": [
      110.768251,
      33.990967
    ],
    "f9dafa255b774af08003811e33c9de10": [
      115.367576,
      33.399821
    ],
    "53f3da71ab124333aff0ad35b915e6ac": [
      116.342632,
      37.501695
    ],
    "7e821d134dd64bc587f31ea73156bfc0": [
      116.360495,
      34.836477
    ],
    "b8d343de07304c4fb378db198febd45f": [
      117.440802,
      34.944583
    ],
    "81a5cd1eb9d04b92b0d955fc269b35fc": [
      115.767717,
      35.702342
    ],
    "8425a827de3e48548387ff0f92c62791": [
      115.783878,
      34.308761
    ]
  },
  "resultData": [
    [
      [
        {
          "entName": "王氏中医医院有限责任公司",
          "code": "cbbb669db45c4fe19ce9074bfb4cd1e8"
        },
        {
          "entName": "汇楚危险废物处置有限公司",
          "code": "8425a827de3e48548387ff0f92c62791"
        }
      ]
    ],
    [
      [
        {
          "entName": "社区卫生服务中心",
          "code": "e3fb0b7892f74cff96f008567194d947"
        },
        {
          "entName": "汇楚危险废物处置有限公司",
          "code": "8425a827de3e48548387ff0f92c62791"
        }
      ]
    ],
    [
      [
        {
          "entName": "济堂风湿病专科医院",
          "code": "f9dafa255b774af08003811e33c9de10"
        },
        {
          "entName": "汇楚危险废物处置有限公司",
          "code": "8425a827de3e48548387ff0f92c62791"
        }
      ]
    ],
    [
      [
        {
          "entName": "红济中医医院",
          "code": "53f3da71ab124333aff0ad35b915e6ac"
        },
        {
          "entName": "汇楚危险废物处置有限公司",
          "code": "8425a827de3e48548387ff0f92c62791"
        }
      ]
    ],
    [
      [
        {
          "entName": "温泉社区卫生服务中心",
          "code": "7e821d134dd64bc587f31ea73156bfc0"
        },
        {
          "entName": "汇楚危险废物处置有限公司",
          "code": "8425a827de3e48548387ff0f92c62791"
        }
      ]
    ],
    [
      [
        {
          "entName": "温泉社区卫生服务中心",
          "code": "b8d343de07304c4fb378db198febd45f"
        },
        {
          "entName": "汇楚危险废物处置有限公司",
          "code": "8425a827de3e48548387ff0f92c62791"
        }
      ]
    ],
    [
      [
        {
          "entName": "社区卫生服务中心",
          "code": "81a5cd1eb9d04b92b0d955fc269b35fc"
        },
        {
          "entName": "汇楚危险废物处置有限公司",
          "code": "8425a827de3e48548387ff0f92c62791"
        }
      ]
    ]
  ]
}

四、框架内配置加载信息

qxt:{
  entities:[],
  isRLayerPanel: true,
  dataIdField: 'code',
  dataLabelField: 'entName',
  dataPath: '',
  options:{
    id:'qxt',
    url: '/static/EchartsData/transferData.json',
    name:'迁徙图',
    isShow:true
  },
  location: {
    "destination":{"x":-4739343.203207548,"y":10948294.24246299,"z":8769980.74531059},
    "orientation":{"heading":6.230093908112224,"pitch":-1.567082607022392,"roll":0},
    duration: 2
  },
  entityType:'EchartsQXT'
}

五、框架内调用解析代码编写

if (layersInfo[layerId].entityType === "EchartsQXT") {
  if (ZJNCesium.echartsLayerUtil === null) {
    ZJNCesium.echartsLayerUtil = new EchartsLayerUtil(ZJNCesium)
  }
  let _this = ZJNCesium
  getMapData(layersInfo[layerId].options.url).then((res) => {
    if (layersInfo[layerId].dataPath != undefined && layersInfo[layerId].dataPath != "") {
      let dp = layersInfo[layerId].dataPath.split('/')
      for (let i = 0; i < dp.length; i++) {
        res = res[dp[i]]
      }
    }
    _this.echartsLayerUtil.createTransferLayer(res, layersInfo[layerId].dataIdField, layersInfo[layerId].dataLabelField)
    layersInfo[layerId].echartsLayer = _this.echartsLayerUtil.transferLayer
    if( layersInfo[layerId].options.isShow){
      layersInfo[layerId].echartsLayer.chart.getDom().style.display = ''
    }else {
      layersInfo[layerId].echartsLayer.chart.getDom().style.display = 'none'
    }
  });
}

六、成果展示

 

 感谢支持技术分享,请扫码点赞支持:

技术合作交流qq:2401315930

 

GitHub 加速计划 / vu / vue
207.53 K
33.66 K
下载
vuejs/vue: 是一个用于构建用户界面的 JavaScript 框架,具有简洁的语法和丰富的组件库,可以用于开发单页面应用程序和多页面应用程序。
最近提交(Master分支:2 个月前 )
73486cb5 * chore: fix link broken Signed-off-by: snoppy <michaleli@foxmail.com> * Update packages/template-compiler/README.md [skip ci] --------- Signed-off-by: snoppy <michaleli@foxmail.com> Co-authored-by: Eduardo San Martin Morote <posva@users.noreply.github.com> 4 个月前
e428d891 Updated Browser Compatibility reference. The previous currently returns HTTP 404. 4 个月前
Logo

旨在为数千万中国开发者提供一个无缝且高效的云端环境,以支持学习、使用和贡献开源项目。

更多推荐