BMapCoordSys.js 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199
  1. /* global BMap */
  2. import {
  3. util as zrUtil,
  4. graphic,
  5. matrix
  6. } from 'echarts';
  7. function BMapCoordSys(bmap, api) {
  8. this._bmap = bmap;
  9. this.dimensions = ['lng', 'lat'];
  10. this._mapOffset = [0, 0];
  11. this._api = api;
  12. this._projection = new BMap.MercatorProjection();
  13. }
  14. BMapCoordSys.prototype.dimensions = ['lng', 'lat'];
  15. BMapCoordSys.prototype.setZoom = function (zoom) {
  16. this._zoom = zoom;
  17. };
  18. BMapCoordSys.prototype.setCenter = function (center) {
  19. this._center = this._projection.lngLatToPoint(new BMap.Point(center[0], center[1]));
  20. };
  21. BMapCoordSys.prototype.setMapOffset = function (mapOffset) {
  22. this._mapOffset = mapOffset;
  23. };
  24. BMapCoordSys.prototype.getBMap = function () {
  25. return this._bmap;
  26. };
  27. BMapCoordSys.prototype.dataToPoint = function (data) {
  28. var point = new BMap.Point(data[0], data[1]);
  29. // TODO mercator projection is toooooooo slow
  30. // var mercatorPoint = this._projection.lngLatToPoint(point);
  31. // var width = this._api.getZr().getWidth();
  32. // var height = this._api.getZr().getHeight();
  33. // var divider = Math.pow(2, 18 - 10);
  34. // return [
  35. // Math.round((mercatorPoint.x - this._center.x) / divider + width / 2),
  36. // Math.round((this._center.y - mercatorPoint.y) / divider + height / 2)
  37. // ];
  38. var px = this._bmap.pointToOverlayPixel(point);
  39. var mapOffset = this._mapOffset;
  40. return [px.x - mapOffset[0], px.y - mapOffset[1]];
  41. };
  42. BMapCoordSys.prototype.pointToData = function (pt) {
  43. var mapOffset = this._mapOffset;
  44. var pt = this._bmap.overlayPixelToPoint({
  45. x: pt[0] + mapOffset[0],
  46. y: pt[1] + mapOffset[1]
  47. });
  48. return [pt.lng, pt.lat];
  49. };
  50. BMapCoordSys.prototype.getViewRect = function () {
  51. var api = this._api;
  52. return new graphic.BoundingRect(0, 0, api.getWidth(), api.getHeight());
  53. };
  54. BMapCoordSys.prototype.getRoamTransform = function () {
  55. return matrix.create();
  56. };
  57. BMapCoordSys.prototype.prepareCustoms = function (data) {
  58. var rect = this.getViewRect();
  59. return {
  60. coordSys: {
  61. // The name exposed to user is always 'cartesian2d' but not 'grid'.
  62. type: 'bmap',
  63. x: rect.x,
  64. y: rect.y,
  65. width: rect.width,
  66. height: rect.height
  67. },
  68. api: {
  69. coord: zrUtil.bind(this.dataToPoint, this),
  70. size: zrUtil.bind(dataToCoordSize, this)
  71. }
  72. };
  73. };
  74. function dataToCoordSize(dataSize, dataItem) {
  75. dataItem = dataItem || [0, 0];
  76. return zrUtil.map([0, 1], function (dimIdx) {
  77. var val = dataItem[dimIdx];
  78. var halfSize = dataSize[dimIdx] / 2;
  79. var p1 = [];
  80. var p2 = [];
  81. p1[dimIdx] = val - halfSize;
  82. p2[dimIdx] = val + halfSize;
  83. p1[1 - dimIdx] = p2[1 - dimIdx] = dataItem[1 - dimIdx];
  84. return Math.abs(this.dataToPoint(p1)[dimIdx] - this.dataToPoint(p2)[dimIdx]);
  85. }, this);
  86. }
  87. var Overlay;
  88. // For deciding which dimensions to use when creating list data
  89. BMapCoordSys.dimensions = BMapCoordSys.prototype.dimensions;
  90. function createOverlayCtor() {
  91. function Overlay(root) {
  92. this._root = root;
  93. }
  94. Overlay.prototype = new BMap.Overlay();
  95. /**
  96. * 初始化
  97. *
  98. * @param {BMap.Map} map
  99. * @override
  100. */
  101. Overlay.prototype.initialize = function (map) {
  102. map.getPanes().labelPane.appendChild(this._root);
  103. return this._root;
  104. };
  105. /**
  106. * @override
  107. */
  108. Overlay.prototype.draw = function () {};
  109. return Overlay;
  110. }
  111. BMapCoordSys.create = function (ecModel, api) {
  112. var bmapCoordSys;
  113. var root = api.getDom();
  114. // TODO Dispose
  115. ecModel.eachComponent('bmap', function (bmapModel) {
  116. var painter = api.getZr().painter;
  117. var viewportRoot = painter.getViewportRoot();
  118. if (typeof BMap === 'undefined') {
  119. throw new Error('BMap api is not loaded');
  120. }
  121. Overlay = Overlay || createOverlayCtor();
  122. if (bmapCoordSys) {
  123. throw new Error('Only one bmap component can exist');
  124. }
  125. if (!bmapModel.__bmap) {
  126. // Not support IE8
  127. var bmapRoot = root.querySelector('.ec-extension-bmap');
  128. if (bmapRoot) {
  129. // Reset viewport left and top, which will be changed
  130. // in moving handler in BMapView
  131. viewportRoot.style.left = '0px';
  132. viewportRoot.style.top = '0px';
  133. root.removeChild(bmapRoot);
  134. }
  135. bmapRoot = document.createElement('div');
  136. bmapRoot.style.cssText = 'width:100%;height:100%';
  137. // Not support IE8
  138. bmapRoot.classList.add('ec-extension-bmap');
  139. root.appendChild(bmapRoot);
  140. var bmap = bmapModel.__bmap = new BMap.Map(bmapRoot);
  141. var overlay = new Overlay(viewportRoot);
  142. bmap.addOverlay(overlay);
  143. // Override
  144. painter.getViewportRootOffset = function () {
  145. return {offsetLeft: 0, offsetTop: 0};
  146. };
  147. }
  148. var bmap = bmapModel.__bmap;
  149. // Set bmap options
  150. // centerAndZoom before layout and render
  151. var center = bmapModel.get('center');
  152. var zoom = bmapModel.get('zoom');
  153. if (center && zoom) {
  154. var pt = new BMap.Point(center[0], center[1]);
  155. bmap.centerAndZoom(pt, zoom);
  156. }
  157. bmapCoordSys = new BMapCoordSys(bmap, api);
  158. bmapCoordSys.setMapOffset(bmapModel.__mapOffset || [0, 0]);
  159. bmapCoordSys.setZoom(zoom);
  160. bmapCoordSys.setCenter(center);
  161. bmapModel.coordinateSystem = bmapCoordSys;
  162. });
  163. ecModel.eachSeries(function (seriesModel) {
  164. if (seriesModel.get('coordinateSystem') === 'bmap') {
  165. seriesModel.coordinateSystem = bmapCoordSys;
  166. }
  167. });
  168. };
  169. export default BMapCoordSys;