leaflet-echarts的地图

参考http://wandergis.com/leaflet-echarts/src/leaflet-echarts.js

(function(root, factory) {
  if (typeof define === 'function' && define.amd) {
    // AMD. Register as an anonymous module.
    define(['leaflet'], factory);
  } else if (typeof module === 'object' && module.exports) {
    // Node. Does not work with strict CommonJS, but
    // only CommonJS-like environments that support module.exports,
    // like Node.
    module.exports = factory(require('leaflet'));
  } else if (typeof root !== 'undefined' && root.L) {
    // Browser globals (root is window)
    root.L.echartsLayer = factory(L);
  }
}(this, function(L) {
  L.EchartsLayer = L.Class.extend({
    includes: [L.Mixin.Events],
    _echartsContainer: null,
    _map: null,
    _ec: null,
    _option: null,
    _geoCoord: [],
    _mapOffset: [0, 0],
    _delta: 0,
    _startTime: null,
    _lastMousePos: null,
    initialize: function(map, ec) {
      this._map = map;
      map.scrollWheelZoom.disable();
      var size = map.getSize();
      var div = this._echartsContainer = document.createElement('div');
      div.style.position = 'absolute';
      div.style.height = size.y + 'px';
      div.style.width = size.x + 'px';
      div.style.top = 0;
      div.style.left = 0;
      map.getPanes().overlayPane.appendChild(div);
      this._init(map, ec);
    },
    _init: function(map, ec) {
      var self = this;
      self._map = map;
      //初始化mapoverlay
      /**
       * 获取echarts容器
       *
       * @return {HTMLElement}
       * @public
       */
      self.getEchartsContainer = function() {
        return self._echartsContainer;
      };

      /**
       * 获取map实例
       *
       * @return {map.Map}
       * @public
       */
      self.getMap = function() {
        return self._map;
      };
      /**
       * 经纬度转换为屏幕像素
       *
       * @param {Array.<number>} geoCoord  经纬度
       * @return {Array.<number>}
       * @public
       */
      self.geoCoord2Pixel = function(geoCoord) {
        var point = new L.latLng(geoCoord[1], geoCoord[0]);
        var pos = self._map.latLngToContainerPoint(point);
        return [pos.x, pos.y];
      };

      /**
       * 屏幕像素转换为经纬度
       *
       * @param {Array.<number>} pixel  像素坐标
       * @return {Array.<number>}
       * @public
       */
      self.pixel2GeoCoord = function(pixel) {
        var point = self._map.containerPointToLatLng(L.point(pixel[0], pixel[1]));
        return [point.lng, point.lat];
      };

      /**
       * 初始化echarts实例
       *
       * @return {ECharts}
       * @public
       */
      self.initECharts = function() {
        self._ec = ec.init.apply(self, arguments);
        self._bindEvent();
        self._addMarkWrap();
        return self._ec;
      };

      // addMark wrap for get position from baidu map by geo location
      // by kener at 2015.01.08
      self._addMarkWrap = function() {
        function _addMark(seriesIdx, markData, markType) {
          var data;
          if (markType == 'markPoint') {
            var data = markData.data;
            if (data && data.length) {
              for (var k = 0, len = data.length; k < len; k++) {
                if (!(data[k].name && this._geoCoord.hasOwnProperty(data[k].name))) {
                  data[k].name = k + 'markp';
                  self._geoCoord[data[k].name] = data[k].geoCoord;
                }
                self._AddPos(data[k]);
              }
            }
          } else {
            data = markData.data;
            if (data && data.length) {
              for (var k = 0, len = data.length; k < len; k++) {
                if (!(data[k][0].name && this._geoCoord.hasOwnProperty(data[k][0].name))) {
                  data[k][0].name = k + 'startp';
                  self._geoCoord[data[k][0].name] = data[k][0].geoCoord;
                }
                if (!(data[k][1].name && this._geoCoord.hasOwnProperty(data[k][1].name))) {
                  data[k][1].name = k + 'endp';
                  self._geoCoord[data[k][1].name] = data[k][1].geoCoord;
                }
                self._AddPos(data[k][0]);
                self._AddPos(data[k][1]);
              }
            }
          }
          self._ec._addMarkOri(seriesIdx, markData, markType);
        }

        self._ec._addMarkOri = self._ec._addMark;
        self._ec._addMark = _addMark;
      };

      /**
       * 获取ECharts实例
       *
       * @return {ECharts}
       * @public
       */
      self.getECharts = function() {
        return self._ec;
      };

      /**
       * 获取地图的偏移量
       *
       * @return {Array.<number>}
       * @public
       */
      self.getMapOffset = function() {
        return self._mapOffset;
      };

      /**
       * 对echarts的setOption加一次处理
       * 用来为markPoint、markLine中添加x、y坐标,需要name与geoCoord对应
       *
       * @public
       * @param option
       * @param notMerge
       */
      self.setOption = function(option, notMerge) {
        self._option = option;
        var series = option.series || {};

        // 记录所有的geoCoord
        for (var i = 0, item; item = series[i++];) {
          var geoCoord = item.geoCoord;
          if (geoCoord) {
            for (var k in geoCoord) {
              self._geoCoord[k] = geoCoord[k];
            }
          }
        }

        // 添加x、y
        for (var i = 0, item; item = series[i++];) {
          var markPoint = item.markPoint || {};
          var markLine = item.markLine || {};

          var data = markPoint.data;
          if (data && data.length) {
            for (var k = 0, len = data.length; k < len; k++) {
              if (!(data[k].name && this._geoCoord.hasOwnProperty(data[k].name))) {
                data[k].name = k + 'markp';
                self._geoCoord[data[k].name] = data[k].geoCoord;
              }
              self._AddPos(data[k]);
            }
          }

          data = markLine.data;
          if (data && data.length) {
            for (var k = 0, len = data.length; k < len; k++) {
              if (!(data[k][0].name && this._geoCoord.hasOwnProperty(data[k][0].name))) {
                data[k][0].name = k + 'startp';
                self._geoCoord[data[k][0].name] = data[k][0].geoCoord;
              }
              if (!(data[k][1].name && this._geoCoord.hasOwnProperty(data[k][1].name))) {
                data[k][1].name = k + 'endp';
                self._geoCoord[data[k][1].name] = data[k][1].geoCoord;
              }
              self._AddPos(data[k][0]);
              self._AddPos(data[k][1]);
            }
          }
        }

        self._ec.setOption(option, notMerge);
      };

      /**
       * 增加x、y坐标
       *
       * @param {Object} obj  markPoint、markLine data中的项,必须有name
       * @param {Object} geoCoord
       */
      self._AddPos = function(obj) {

        var coord = self._geoCoord[obj.name];
        var pos = self.geoCoord2Pixel(coord);
        obj.x = pos[0]; //- self._mapOffset[0];
        obj.y = pos[1]; //- self._mapOffset[1];
      };

      /**
       * 绑定地图事件的处理方法
       *
       * @private
       */
      self._bindEvent = function() {
        self._map.on('move', _moveHandler('moving'));
        self._map.on('moveend', _moveHandler('moveend'));
        self._map.on('zoomstart', function() {
          self._ec.clear();
        });
        self._map.on('zoomend', _zoomChangeHandler);
        self._ec.getZrender().on('dragstart', _dragZrenderHandler(true));
        self._ec.getZrender().on('dragend', _dragZrenderHandler(false));
        self._ec.getZrender().on('mouseup', function() {
          // self.setOption(self._option);
          //修改了echarts源码解决了这个问题
        });
        self._ec.getZrender().on('mousedown', function() {
          // self._ec.clear();
          //修改了echarts源码解决了这个问题
        });
        self._ec.getZrender().on('mousewheel', function(e) {
          self._ec.clear(); //在mousewheel的时候清除echarts内容
          self._lastMousePos = self._map.mouseEventToContainerPoint(e.event);
          var delta = L.DomEvent.getWheelDelta(e.event);
          var map = self._map,
            zoom = map.getZoom();
          delta = delta > 0 ? Math.ceil(delta) : Math.floor(delta);
          delta = Math.max(Math.min(delta, 4), -4);
          delta = map._limitZoom(zoom + delta) - zoom;

          self._delta = 0;
          self._startTime = null;

          if (!delta) {
            return;
          }

          if (map.options.scrollWheelZoom === 'center') {
            map.setZoom(zoom + delta);
          } else {
            map.setZoomAround(self._lastMousePos, zoom + delta);
          }
        });
      };

      /**
       * 地图缩放触发事件
       *
       * @private
       */
      function _zoomChangeHandler() {
        self.setOption(self._option);
      }

      // function _zoomatartChangeHandler() {
      //   self._ec.clear();
      // }

      /**
       * 地图移动、如拖拽触发事件
       *
       * @param {string} type moving | moveend  移动中|移动结束
       * @return {Function}
       * @private
       */
      function _moveHandler(type) {
        return function() {
          var domPosition = self._map._getMapPanePos();
          // 记录偏移量
          self._mapOffset = [-parseInt(domPosition.x) || 0, -parseInt(domPosition.y) || 0];
          self._echartsContainer.style.left = self._mapOffset[0] + 'px';
          self._echartsContainer.style.top = self._mapOffset[1] + 'px';
          //_fireEvent(type);
          if (type == 'moving') {
            self._ec.clear();
          }
          if (type == 'moveend') {
            self.setOption(self._option);
          }
        }
      }

      /**
       * Zrender拖拽触发事件
       *
       * @param {boolean} isStart
       * @return {Function}
       * @private
       */
      function _dragZrenderHandler(isStart) {

        return function() {
          var func = isStart ? 'disable' : 'enable';
          if (isStart) {
            self._ec.clear();
          } else {
            self.setOption(self._option);
          }
          self._map.dragging[func]();
        };
      }
    }
  });
  L.echartsLayer = function(map, ec) {
    return new L.EchartsLayer(map, ec);
  };
  return L.echartsLayer;
}));

 

看了这个源码之后一直有个疑问就是echarts的地图坐标和地图本身的坐标怎么对应上,因为我们在使用echarts时是,传入的坐标都是经纬度,这就说明它本身是有坐标系的,这个怎么和自己地图的坐标系对应起来呢。

后来发现echarts里options参数的series里面有个mapType参数,mapType为undefined时参数坐标的值为经纬度,mapType为none时参数的坐标轴为屏幕像素;

搞明白了这个,就好理解上面的源码了。参考这个源码就可以实现arcgis或者openLayers的扩展。

posted on 2016-05-19 19:34  时光飞仔  阅读(7187)  评论(2编辑  收藏  举报

导航