园林绿化
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

9230 lines
295 KiB

  1. (function (global, factory) {
  2. typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :
  3. typeof define === 'function' && define.amd ? define(['exports'], factory) :
  4. (factory((global.mapv = global.mapv || {})));
  5. }(this, (function (exports) { 'use strict';
  6. var version = "2.0.62";
  7. /**
  8. * @author kyle / http://nikai.us/
  9. */
  10. var clear = function (context) {
  11. context && context.clearRect && context.clearRect(0, 0, context.canvas.width, context.canvas.height);
  12. //context.canvas.width = context.canvas.width;
  13. //context.canvas.height = context.canvas.height;
  14. };
  15. /**
  16. * @author kyle / http://nikai.us/
  17. */
  18. var resolutionScale$1 = function (context) {
  19. var devicePixelRatio = 1 || 1;
  20. context.canvas.width = context.canvas.width * devicePixelRatio;
  21. context.canvas.height = context.canvas.height * devicePixelRatio;
  22. context.canvas.style.width = context.canvas.width / devicePixelRatio + 'px';
  23. context.canvas.style.height = context.canvas.height / devicePixelRatio + 'px';
  24. context.scale(devicePixelRatio, devicePixelRatio);
  25. };
  26. function Event() {
  27. this._subscribers = {}; // event subscribers
  28. }
  29. /**
  30. * Subscribe to an event, add an event listener
  31. * @param {String} event Event name. Available events: 'put', 'update',
  32. * 'remove'
  33. * @param {function} callback Callback method. Called with three parameters:
  34. * {String} event
  35. * {Object | null} params
  36. * {String | Number} senderId
  37. */
  38. Event.prototype.on = function (event, callback) {
  39. var subscribers = this._subscribers[event];
  40. if (!subscribers) {
  41. subscribers = [];
  42. this._subscribers[event] = subscribers;
  43. }
  44. subscribers.push({
  45. callback: callback
  46. });
  47. };
  48. /**
  49. * Unsubscribe from an event, remove an event listener
  50. * @param {String} event
  51. * @param {function} callback
  52. */
  53. Event.prototype.off = function (event, callback) {
  54. var subscribers = this._subscribers[event];
  55. if (subscribers) {
  56. //this._subscribers[event] = subscribers.filter(listener => listener.callback != callback);
  57. for (var i = 0; i < subscribers.length; i++) {
  58. if (subscribers[i].callback == callback) {
  59. subscribers.splice(i, 1);
  60. i--;
  61. }
  62. }
  63. }
  64. };
  65. /**
  66. * Trigger an event
  67. * @param {String} event
  68. * @param {Object | null} params
  69. * @param {String} [senderId] Optional id of the sender.
  70. * @private
  71. */
  72. Event.prototype._trigger = function (event, params, senderId) {
  73. if (event == '*') {
  74. throw new Error('Cannot trigger event *');
  75. }
  76. var subscribers = [];
  77. if (event in this._subscribers) {
  78. subscribers = subscribers.concat(this._subscribers[event]);
  79. }
  80. if ('*' in this._subscribers) {
  81. subscribers = subscribers.concat(this._subscribers['*']);
  82. }
  83. for (var i = 0, len = subscribers.length; i < len; i++) {
  84. var subscriber = subscribers[i];
  85. if (subscriber.callback) {
  86. subscriber.callback(event, params, senderId || null);
  87. }
  88. }
  89. };
  90. /**
  91. * get the center by the city name
  92. * @author kyle / http://nikai.us/
  93. */
  94. var citycenter = { municipalities: [{ n: "北京", g: "116.395645,39.929986|12" }, { n: "上海", g: "121.487899,31.249162|12" }, { n: "天津", g: "117.210813,39.14393|12" }, { n: "重庆", g: "106.530635,29.544606|12" }], provinces: [{ n: "安徽", g: "117.216005,31.859252|8", cities: [{ n: "合肥", g: "117.282699,31.866942|12" }, { n: "安庆", g: "117.058739,30.537898|13" }, { n: "蚌埠", g: "117.35708,32.929499|13" }, { n: "亳州", g: "115.787928,33.871211|13" }, { n: "巢湖", g: "117.88049,31.608733|13" }, { n: "池州", g: "117.494477,30.660019|14" }, { n: "滁州", g: "118.32457,32.317351|13" }, { n: "阜阳", g: "115.820932,32.901211|13" }, { n: "淮北", g: "116.791447,33.960023|13" }, { n: "淮南", g: "117.018639,32.642812|13" }, { n: "黄山", g: "118.29357,29.734435|13" }, { n: "六安", g: "116.505253,31.755558|13" }, { n: "马鞍山", g: "118.515882,31.688528|13" }, { n: "宿州", g: "116.988692,33.636772|13" }, { n: "铜陵", g: "117.819429,30.94093|14" }, { n: "芜湖", g: "118.384108,31.36602|12" }, { n: "宣城", g: "118.752096,30.951642|13" }] }, { n: "福建", g: "117.984943,26.050118|8", cities: [{ n: "福州", g: "119.330221,26.047125|12" }, { n: "龙岩", g: "117.017997,25.078685|13" }, { n: "南平", g: "118.181883,26.643626|13" }, { n: "宁德", g: "119.542082,26.656527|14" }, { n: "莆田", g: "119.077731,25.44845|13" }, { n: "泉州", g: "118.600362,24.901652|12" }, { n: "三明", g: "117.642194,26.270835|14" }, { n: "厦门", g: "118.103886,24.489231|12" }, { n: "漳州", g: "117.676205,24.517065|12" }] }, { n: "甘肃", g: "102.457625,38.103267|6", cities: [{ n: "兰州", g: "103.823305,36.064226|12" }, { n: "白银", g: "104.171241,36.546682|13" }, { n: "定西", g: "104.626638,35.586056|13" }, { n: "甘南州", g: "102.917442,34.992211|14" }, { n: "嘉峪关", g: "98.281635,39.802397|13" }, { n: "金昌", g: "102.208126,38.516072|13" }, { n: "酒泉", g: "98.508415,39.741474|13" }, { n: "临夏州", g: "103.215249,35.598514|13" }, { n: "陇南", g: "104.934573,33.39448|14" }, { n: "平凉", g: "106.688911,35.55011|13" }, { n: "庆阳", g: "107.644227,35.726801|13" }, { n: "天水", g: "105.736932,34.584319|13" }, { n: "武威", g: "102.640147,37.933172|13" }, { n: "张掖", g: "100.459892,38.93932|13" }] }, { n: "广东", g: "113.394818,23.408004|8", cities: [{ n: "广州", g: "113.30765,23.120049|12" }, { n: "潮州", g: "116.630076,23.661812|13" }, { n: "东莞", g: "113.763434,23.043024|12" }, { n: "佛山", g: "113.134026,23.035095|13" }, { n: "河源", g: "114.713721,23.757251|12" }, { n: "惠州", g: "114.410658,23.11354|12" }, { n: "江门", g: "113.078125,22.575117|13" }, { n: "揭阳", g: "116.379501,23.547999|13" }, { n: "茂名", g: "110.931245,21.668226|13" }, { n: "梅州", g: "116.126403,24.304571|13" }, { n: "清远", g: "113.040773,23.698469|13" }, { n: "汕头", g: "116.72865,23.383908|13" }, { n: "汕尾", g: "115.372924,22.778731|14" }, { n: "韶关", g: "113.594461,24.80296|13" }, { n: "深圳", g: "114.025974,22.546054|12" }, { n: "阳江", g: "111.97701,21.871517|14" }, { n: "云浮", g: "112.050946,22.937976|13" }, { n: "湛江", g: "110.365067,21.257463|13" }, { n: "肇庆", g: "112.479653,23.078663|13" }, { n: "中山", g: "113.42206,22.545178|12" }, { n: "珠海", g: "113.562447,22.256915|13" }] }, { n: "广西", g: "108.924274,23.552255|7", cities: [{ n: "南宁", g: "108.297234,22.806493|12" }, { n: "百色", g: "106.631821,23.901512|13" }, { n: "北海", g: "109.122628,21.472718|13" }, { n: "崇左", g: "107.357322,22.415455|14" }, { n: "防城港", g: "108.351791,21.617398|15" }, { n: "桂林", g: "110.26092,25.262901|12" }, { n: "贵港", g: "109.613708,23.103373|13" }, { n: "河池", g: "108.069948,24.699521|14" }, { n: "贺州", g: "111.552594,24.411054|14" }, { n: "来宾", g: "109.231817,23.741166|14" }, { n: "柳州", g: "109.422402,24.329053|12" }, { n: "钦州", g: "108.638798,21.97335|13" }, { n: "梧州", g: "111.305472,23.485395|13" }, { n: "玉林", g: "110.151676,22.643974|14" }] }, { n: "贵州", g: "106.734996,26.902826|8", cities: [{ n: "
  95. function getCenter(g) {
  96. var item = g.split("|");
  97. item[0] = item[0].split(",");
  98. return {
  99. lng: parseFloat(item[0][0]),
  100. lat: parseFloat(item[0][1])
  101. };
  102. }
  103. var cityCenter = {
  104. getProvinceNameByCityName: function getProvinceNameByCityName(name) {
  105. var provinces = citycenter.provinces;
  106. for (var i = 0; i < provinces.length; i++) {
  107. var provinceName = provinces[i].n;
  108. var cities = provinces[i].cities;
  109. for (var j = 0; j < cities.length; j++) {
  110. if (cities[j].n == name) {
  111. return provinceName;
  112. }
  113. }
  114. }
  115. return null;
  116. },
  117. getCenterByCityName: function getCenterByCityName(name) {
  118. name = name.replace('市', '');
  119. for (var i = 0; i < citycenter.municipalities.length; i++) {
  120. if (citycenter.municipalities[i].n == name) {
  121. return getCenter(citycenter.municipalities[i].g);
  122. }
  123. }
  124. for (var i = 0; i < citycenter.other.length; i++) {
  125. if (citycenter.other[i].n == name) {
  126. return getCenter(citycenter.other[i].g);
  127. }
  128. }
  129. var provinces = citycenter.provinces;
  130. for (var i = 0; i < provinces.length; i++) {
  131. if (provinces[i].n == name) {
  132. return getCenter(provinces[i].g);
  133. }
  134. var cities = provinces[i].cities;
  135. for (var j = 0; j < cities.length; j++) {
  136. if (cities[j].n == name) {
  137. return getCenter(cities[j].g);
  138. }
  139. }
  140. }
  141. return null;
  142. }
  143. };
  144. var classCallCheck = function (instance, Constructor) {
  145. if (!(instance instanceof Constructor)) {
  146. throw new TypeError("Cannot call a class as a function");
  147. }
  148. };
  149. var createClass = function () {
  150. function defineProperties(target, props) {
  151. for (var i = 0; i < props.length; i++) {
  152. var descriptor = props[i];
  153. descriptor.enumerable = descriptor.enumerable || false;
  154. descriptor.configurable = true;
  155. if ("value" in descriptor) descriptor.writable = true;
  156. Object.defineProperty(target, descriptor.key, descriptor);
  157. }
  158. }
  159. return function (Constructor, protoProps, staticProps) {
  160. if (protoProps) defineProperties(Constructor.prototype, protoProps);
  161. if (staticProps) defineProperties(Constructor, staticProps);
  162. return Constructor;
  163. };
  164. }();
  165. var get = function get(object, property, receiver) {
  166. if (object === null) object = Function.prototype;
  167. var desc = Object.getOwnPropertyDescriptor(object, property);
  168. if (desc === undefined) {
  169. var parent = Object.getPrototypeOf(object);
  170. if (parent === null) {
  171. return undefined;
  172. } else {
  173. return get(parent, property, receiver);
  174. }
  175. } else if ("value" in desc) {
  176. return desc.value;
  177. } else {
  178. var getter = desc.get;
  179. if (getter === undefined) {
  180. return undefined;
  181. }
  182. return getter.call(receiver);
  183. }
  184. };
  185. var inherits = function (subClass, superClass) {
  186. if (typeof superClass !== "function" && superClass !== null) {
  187. throw new TypeError("Super expression must either be null or a function, not " + typeof superClass);
  188. }
  189. subClass.prototype = Object.create(superClass && superClass.prototype, {
  190. constructor: {
  191. value: subClass,
  192. enumerable: false,
  193. writable: true,
  194. configurable: true
  195. }
  196. });
  197. if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass;
  198. };
  199. var possibleConstructorReturn = function (self, call) {
  200. if (!self) {
  201. throw new ReferenceError("this hasn't been initialised - super() hasn't been called");
  202. }
  203. return call && (typeof call === "object" || typeof call === "function") ? call : self;
  204. };
  205. var slicedToArray = function () {
  206. function sliceIterator(arr, i) {
  207. var _arr = [];
  208. var _n = true;
  209. var _d = false;
  210. var _e = undefined;
  211. try {
  212. for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) {
  213. _arr.push(_s.value);
  214. if (i && _arr.length === i) break;
  215. }
  216. } catch (err) {
  217. _d = true;
  218. _e = err;
  219. } finally {
  220. try {
  221. if (!_n && _i["return"]) _i["return"]();
  222. } finally {
  223. if (_d) throw _e;
  224. }
  225. }
  226. return _arr;
  227. }
  228. return function (arr, i) {
  229. if (Array.isArray(arr)) {
  230. return arr;
  231. } else if (Symbol.iterator in Object(arr)) {
  232. return sliceIterator(arr, i);
  233. } else {
  234. throw new TypeError("Invalid attempt to destructure non-iterable instance");
  235. }
  236. };
  237. }();
  238. /**
  239. * @author kyle / http://nikai.us/
  240. */
  241. /**
  242. * DataSet
  243. *
  244. * A data set can:
  245. * - add/remove/update data
  246. * - gives triggers upon changes in the data
  247. * - can import/export data in various data formats
  248. * @param {Array} [data] Optional array with initial data
  249. * the field geometry is like geojson, it can be:
  250. * {
  251. * "type": "Point",
  252. * "coordinates": [125.6, 10.1]
  253. * }
  254. * {
  255. * "type": "LineString",
  256. * "coordinates": [
  257. * [102.0, 0.0], [103.0, 1.0], [104.0, 0.0], [105.0, 1.0]
  258. * ]
  259. * }
  260. * {
  261. * "type": "Polygon",
  262. * "coordinates": [
  263. * [ [100.0, 0.0], [101.0, 0.0], [101.0, 1.0],
  264. * [100.0, 1.0], [100.0, 0.0] ]
  265. * ]
  266. * }
  267. * @param {Object} [options] Available options:
  268. *
  269. */
  270. function DataSet(data, options) {
  271. Event.bind(this)();
  272. // alert(2)
  273. this._options = options || {};
  274. this._data = []; // map with data indexed by id
  275. // add initial data when provided
  276. if (data) {
  277. this.add(data);
  278. }
  279. }
  280. DataSet.prototype = Object.create(Event.prototype);
  281. /**
  282. * Add data.
  283. */
  284. DataSet.prototype.add = function (data, senderId) {
  285. if (Array.isArray(data)) {
  286. // Array
  287. for (var i = 0, len = data.length; i < len; i++) {
  288. if (data[i]) {
  289. if (data[i].time && data[i].time.length == 14 && data[i].time.substr(0, 2) == '20') {
  290. var time = data[i].time;
  291. data[i].time = new Date(time.substr(0, 4) + '-' + time.substr(4, 2) + '-' + time.substr(6, 2) + ' ' + time.substr(8, 2) + ':' + time.substr(10, 2) + ':' + time.substr(12, 2)).getTime();
  292. }
  293. this._data.push(data[i]);
  294. }
  295. }
  296. } else if (data instanceof Object) {
  297. // Single item
  298. this._data.push(data);
  299. } else {
  300. throw new Error('Unknown dataType');
  301. }
  302. this._dataCache = JSON.parse(JSON.stringify(this._data));
  303. };
  304. DataSet.prototype.reset = function () {
  305. this._data = JSON.parse(JSON.stringify(this._dataCache));
  306. };
  307. /**
  308. * get data.
  309. */
  310. DataSet.prototype.get = function (args) {
  311. args = args || {};
  312. //console.time('copy data time')
  313. var start = new Date();
  314. // TODO: 不修改原始数据,在数据上挂载新的名称,每次修改数据直接修改新名称下的数据,可以省去deepCopy
  315. // var data = deepCopy(this._data);
  316. var data = this._data;
  317. var start = new Date();
  318. if (args.filter) {
  319. var newData = [];
  320. for (var i = 0; i < data.length; i++) {
  321. if (args.filter(data[i])) {
  322. newData.push(data[i]);
  323. }
  324. }
  325. data = newData;
  326. }
  327. if (args.transferCoordinate) {
  328. data = this.transferCoordinate(data, args.transferCoordinate, args.fromColumn, args.toColumn);
  329. }
  330. // console.timeEnd('transferCoordinate time')
  331. return data;
  332. };
  333. /**
  334. * set data.
  335. */
  336. DataSet.prototype.set = function (data) {
  337. this._set(data);
  338. this._trigger('change');
  339. };
  340. /**
  341. * set data.
  342. */
  343. DataSet.prototype._set = function (data) {
  344. this.clear();
  345. this.add(data);
  346. };
  347. /**
  348. * clear data.
  349. */
  350. DataSet.prototype.clear = function (args) {
  351. this._data = []; // map with data indexed by id
  352. };
  353. /**
  354. * remove data.
  355. */
  356. DataSet.prototype.remove = function (args) {};
  357. /**
  358. * update data.
  359. */
  360. DataSet.prototype.update = function (cbk, condition) {
  361. var data = this._data;
  362. var item = null;
  363. for (var i = 0; i < data.length; i++) {
  364. if (condition) {
  365. var flag = true;
  366. for (var key in condition) {
  367. if (data[i][key] != condition[key]) {
  368. flag = false;
  369. }
  370. }
  371. if (flag) {
  372. cbk && cbk(data[i]);
  373. }
  374. } else {
  375. cbk && cbk(data[i]);
  376. }
  377. }
  378. this._dataCache = JSON.parse(JSON.stringify(this._data));
  379. this._trigger('change');
  380. };
  381. /**
  382. * transfer coordinate.
  383. */
  384. DataSet.prototype.transferCoordinate = function (data, transferFn, fromColumn, toColumnName) {
  385. toColumnName = toColumnName || '_coordinates';
  386. fromColumn = fromColumn || 'coordinates';
  387. for (var i = 0; i < data.length; i++) {
  388. var geometry = data[i].geometry;
  389. var coordinates = geometry[fromColumn];
  390. switch (geometry.type) {
  391. case 'Point':
  392. geometry[toColumnName] = transferFn(coordinates);
  393. break;
  394. case 'LineString':
  395. var newCoordinates = [];
  396. for (var j = 0; j < coordinates.length; j++) {
  397. newCoordinates.push(transferFn(coordinates[j]));
  398. }
  399. geometry[toColumnName] = newCoordinates;
  400. break;
  401. case 'MultiLineString':
  402. case 'Polygon':
  403. var newCoordinates = getPolygon(coordinates);
  404. geometry[toColumnName] = newCoordinates;
  405. break;
  406. case 'MultiPolygon':
  407. var newCoordinates = [];
  408. for (var c = 0; c < coordinates.length; c++) {
  409. var polygon = coordinates[c];
  410. var polygon = getPolygon(polygon);
  411. newCoordinates.push(polygon);
  412. }
  413. geometry[toColumnName] = newCoordinates;
  414. break;
  415. }
  416. }
  417. function getPolygon(coordinates) {
  418. var newCoordinates = [];
  419. for (var c = 0; c < coordinates.length; c++) {
  420. var coordinate = coordinates[c];
  421. var newcoordinate = [];
  422. for (var j = 0; j < coordinate.length; j++) {
  423. newcoordinate.push(transferFn(coordinate[j]));
  424. }
  425. newCoordinates.push(newcoordinate);
  426. }
  427. return newCoordinates;
  428. }
  429. return data;
  430. };
  431. DataSet.prototype.initGeometry = function (transferFn) {
  432. if (transferFn) {
  433. this._data.forEach(function (item) {
  434. item.geometry = transferFn(item);
  435. });
  436. } else {
  437. this._data.forEach(function (item) {
  438. if (!item.geometry) {
  439. if (item.lng && item.lat) {
  440. item.geometry = {
  441. type: 'Point',
  442. coordinates: [item.lng, item.lat]
  443. };
  444. } else if (item.city) {
  445. var center = cityCenter.getCenterByCityName(item.city);
  446. if (center) {
  447. item.geometry = {
  448. type: 'Point',
  449. coordinates: [center.lng, center.lat]
  450. };
  451. }
  452. }
  453. }
  454. });
  455. }
  456. };
  457. /**
  458. * 获取当前列的最大值
  459. */
  460. DataSet.prototype.getMax = function (columnName) {
  461. var data = this._data;
  462. if (!data || data.length <= 0) {
  463. return;
  464. }
  465. var max = parseFloat(data[0][columnName]);
  466. for (var i = 1; i < data.length; i++) {
  467. var value = parseFloat(data[i][columnName]);
  468. if (value > max) {
  469. max = value;
  470. }
  471. }
  472. return max;
  473. };
  474. /**
  475. * 获取当前列的总和
  476. */
  477. DataSet.prototype.getSum = function (columnName) {
  478. var data = this._data;
  479. if (!data || data.length <= 0) {
  480. return;
  481. }
  482. var sum = 0;
  483. for (var i = 0; i < data.length; i++) {
  484. if (data[i][columnName]) {
  485. sum += parseFloat(data[i][columnName]);
  486. }
  487. }
  488. return sum;
  489. };
  490. /**
  491. * 获取当前列的最小值
  492. */
  493. DataSet.prototype.getMin = function (columnName) {
  494. var data = this._data;
  495. if (!data || data.length <= 0) {
  496. return;
  497. }
  498. var min = parseFloat(data[0][columnName]);
  499. for (var i = 1; i < data.length; i++) {
  500. var value = parseFloat(data[i][columnName]);
  501. if (value < min) {
  502. min = value;
  503. }
  504. }
  505. return min;
  506. };
  507. /**
  508. * 获取去重的数据
  509. */
  510. DataSet.prototype.getUnique = function (columnName) {
  511. var data = this._data;
  512. if (!data || data.length <= 0) {
  513. return;
  514. }
  515. var maps = {};
  516. for (var i = 1; i < data.length; i++) {
  517. maps[data[i][columnName]] = true;
  518. }
  519. var data = [];
  520. for (var key in maps) {
  521. data.push(key);
  522. }
  523. return data;
  524. };
  525. function hex_corner(center, size, i) {
  526. var angle_deg = 60 * i + 30;
  527. var angle_rad = Math.PI / 180 * angle_deg;
  528. return [center.x + size * Math.cos(angle_rad), center.y + size * Math.sin(angle_rad)];
  529. }
  530. function draw(context, x, y, size) {
  531. for (var j = 0; j < 6; j++) {
  532. var result = hex_corner({
  533. x: x,
  534. y: y
  535. }, size, j);
  536. context.lineTo(result[0], result[1]);
  537. }
  538. }
  539. /**
  540. * @author kyle / http://nikai.us/
  541. */
  542. var pathSimple = {
  543. drawDataSet: function drawDataSet(context, dataSet, options) {
  544. // alert("drawDataSet");
  545. var data = dataSet instanceof DataSet ? dataSet.get() : dataSet;
  546. for (var i = 0, len = data.length; i < len; i++) {
  547. var item = data[i];
  548. this.draw(context, item, options);
  549. }
  550. },
  551. draw: function draw$$1(context, data, options) {
  552. // alert("draw");
  553. var type = data.geometry.type;
  554. var coordinates = data.geometry._coordinates || data.geometry.coordinates;
  555. var symbol = data.symbol || options.symbol || 'circle';
  556. switch (type) {
  557. case 'Point':
  558. var size = data._size || data.size || options._size || options.size || 5;
  559. if (symbol === 'circle') {
  560. if (options.bigData === 'Point') {
  561. context.moveTo(coordinates[0], coordinates[1]);
  562. }
  563. context.arc(coordinates[0], coordinates[1], size, 0, Math.PI * 2);
  564. } else if (symbol === 'rect') {
  565. context.rect(coordinates[0] - size / 2, coordinates[1] - size / 2, size, size);
  566. } else if (symbol === 'honeycomb') {
  567. draw(context, coordinates[0], coordinates[1], size);
  568. }
  569. break;
  570. case 'LineString':
  571. this.drawLineString(context, coordinates);
  572. break;
  573. case 'MultiLineString':
  574. for (var i = 0; i < coordinates.length; i++) {
  575. var lineString = coordinates[i];
  576. this.drawLineString(context, lineString);
  577. }
  578. break;
  579. case 'Polygon':
  580. this.drawPolygon(context, coordinates);
  581. break;
  582. case 'MultiPolygon':
  583. for (var i = 0; i < coordinates.length; i++) {
  584. var polygon = coordinates[i];
  585. this.drawPolygon(context, polygon);
  586. if (options.multiPolygonDraw) {
  587. var flag = options.multiPolygonDraw();
  588. if (flag) {
  589. return flag;
  590. }
  591. }
  592. }
  593. break;
  594. default:
  595. console.error('type' + type + 'is not support now!');
  596. break;
  597. }
  598. },
  599. drawLineString: function drawLineString(context, coordinates) {
  600. // alert("drawLineString");
  601. for (var j = 0; j < coordinates.length; j++) {
  602. var x = coordinates[j][0];
  603. var y = coordinates[j][1];
  604. if (j == 0) {
  605. context.moveTo(x, y);
  606. } else {
  607. context.lineTo(x, y);
  608. }
  609. }
  610. },
  611. drawPolygon: function drawPolygon(context, coordinates) {
  612. // alert("drawPolygon");
  613. context.beginPath();
  614. for (var i = 0; i < coordinates.length; i++) {
  615. var coordinate = coordinates[i];
  616. context.moveTo(coordinate[0][0], coordinate[0][1]);
  617. for (var j = 1; j < coordinate.length; j++) {
  618. context.lineTo(coordinate[j][0], coordinate[j][1]);
  619. }
  620. context.lineTo(coordinate[0][0], coordinate[0][1]);
  621. context.closePath();
  622. }
  623. }
  624. };
  625. /**
  626. * @author kyle / http://nikai.us/
  627. */
  628. var drawSimple = {
  629. draw: function draw(context, dataSet, options) {
  630. var data = dataSet instanceof DataSet ? dataSet.get() : dataSet;
  631. // console.log('xxxx',options)
  632. context.save();
  633. // alert("drawSimple");
  634. for (var key in options) {
  635. context[key] = options[key];
  636. }
  637. // console.log(data);
  638. if (options.bigData) {
  639. context.save();
  640. context.beginPath();
  641. for (var i = 0, len = data.length; i < len; i++) {
  642. var item = data[i];
  643. pathSimple.draw(context, item, options);
  644. }
  645. var type = options.bigData;
  646. if (type == 'Point' || type == 'Polygon' || type == 'MultiPolygon') {
  647. context.fill();
  648. if (context.lineDash) {
  649. context.setLineDash(context.lineDash);
  650. }
  651. if (item.lineDash) {
  652. context.setLineDash(item.lineDash);
  653. }
  654. if ((item.strokeStyle || options.strokeStyle) && options.lineWidth) {
  655. context.stroke();
  656. }
  657. } else if (type == 'LineString' || type == 'MultiLineString') {
  658. context.stroke();
  659. }
  660. context.restore();
  661. } else {
  662. for (var i = 0, len = data.length; i < len; i++) {
  663. var item = data[i];
  664. context.save();
  665. if (item.fillStyle || item._fillStyle) {
  666. context.fillStyle = item.fillStyle || item._fillStyle;
  667. }
  668. if (item.strokeStyle || item._strokeStyle) {
  669. context.strokeStyle = item.strokeStyle || item._strokeStyle;
  670. }
  671. if (context.lineDash) {
  672. context.setLineDash(context.lineDash);
  673. }
  674. if (item.lineDash) {
  675. context.setLineDash(item.lineDash);
  676. }
  677. var type = item.geometry.type;
  678. context.beginPath();
  679. options.multiPolygonDraw = function () {
  680. context.fill();
  681. if ((item.strokeStyle || options.strokeStyle) && options.lineWidth) {
  682. context.stroke();
  683. }
  684. };
  685. pathSimple.draw(context, item, options);
  686. if (type == 'Point' || type == 'Polygon' || type == 'MultiPolygon') {
  687. context.fill();
  688. if ((item.strokeStyle || options.strokeStyle) && options.lineWidth) {
  689. context.stroke();
  690. }
  691. } else if (type == 'LineString' || type == 'MultiLineString') {
  692. if (item.lineWidth || item._lineWidth) {
  693. context.lineWidth = item.lineWidth || item._lineWidth;
  694. }
  695. context.stroke();
  696. }
  697. context.restore();
  698. }
  699. }
  700. context.restore();
  701. }
  702. };
  703. function Canvas(width, height) {
  704. var canvas;
  705. if (typeof document === 'undefined') {
  706. // var Canvas = require('canvas');
  707. // canvas = new Canvas(width, height);
  708. } else {
  709. var canvas = document.createElement('canvas');
  710. if (width) {
  711. canvas.width = width;
  712. }
  713. if (height) {
  714. canvas.height = height;
  715. }
  716. }
  717. return canvas;
  718. }
  719. /**
  720. * @author kyle / http://nikai.us/
  721. */
  722. /**
  723. * Category
  724. * @param {Object} [options] Available options:
  725. * {Object} gradient: { 0.25: "rgb(0,0,255)", 0.55: "rgb(0,255,0)", 0.85: "yellow", 1.0: "rgb(255,0,0)"}
  726. */
  727. function Intensity(options) {
  728. options = options || {};
  729. this.gradient = options.gradient || {
  730. 0.25: "rgba(0, 0, 255, 1)",
  731. 0.55: "rgba(0, 255, 0, 1)",
  732. 0.85: "rgba(255, 255, 0, 1)",
  733. 1.0: "rgba(255, 0, 0, 1)"
  734. };
  735. this.maxSize = options.maxSize || 35;
  736. this.minSize = options.minSize || 0;
  737. this.max = options.max || 100;
  738. this.min = options.min || 0;
  739. this.initPalette();
  740. }
  741. Intensity.prototype.setMax = function (value) {
  742. this.max = value || 100;
  743. };
  744. Intensity.prototype.setMin = function (value) {
  745. this.min = value || 0;
  746. };
  747. Intensity.prototype.setMaxSize = function (maxSize) {
  748. this.maxSize = maxSize || 35;
  749. };
  750. Intensity.prototype.setMinSize = function (minSize) {
  751. this.minSize = minSize || 0;
  752. };
  753. Intensity.prototype.initPalette = function () {
  754. var gradient = this.gradient;
  755. var canvas = new Canvas(256, 1);
  756. var paletteCtx = this.paletteCtx = canvas.getContext('2d');
  757. var lineGradient = paletteCtx.createLinearGradient(0, 0, 256, 1);
  758. for (var key in gradient) {
  759. lineGradient.addColorStop(parseFloat(key), gradient[key]);
  760. }
  761. paletteCtx.fillStyle = lineGradient;
  762. paletteCtx.fillRect(0, 0, 256, 1);
  763. };
  764. Intensity.prototype.getColor = function (value) {
  765. var imageData = this.getImageData(value);
  766. return "rgba(" + imageData[0] + ", " + imageData[1] + ", " + imageData[2] + ", " + imageData[3] / 256 + ")";
  767. };
  768. Intensity.prototype.getImageData = function (value) {
  769. var imageData = this.paletteCtx.getImageData(0, 0, 256, 1).data;
  770. if (value === undefined) {
  771. return imageData;
  772. }
  773. var max = this.max;
  774. var min = this.min;
  775. if (value > max) {
  776. value = max;
  777. }
  778. if (value < min) {
  779. value = min;
  780. }
  781. var index = Math.floor((value - min) / (max - min) * (256 - 1)) * 4;
  782. return [imageData[index], imageData[index + 1], imageData[index + 2], imageData[index + 3]];
  783. };
  784. /**
  785. * @param Number value
  786. * @param Number max of value
  787. * @param Number max of size
  788. * @param Object other options
  789. */
  790. Intensity.prototype.getSize = function (value) {
  791. var size = 0;
  792. var max = this.max;
  793. var min = this.min;
  794. var maxSize = this.maxSize;
  795. var minSize = this.minSize;
  796. if (value > max) {
  797. value = max;
  798. }
  799. if (value < min) {
  800. value = min;
  801. }
  802. if (max > min) {
  803. size = minSize + (value - min) / (max - min) * (maxSize - minSize);
  804. } else {
  805. return maxSize;
  806. }
  807. return size;
  808. };
  809. Intensity.prototype.getLegend = function (options) {
  810. var gradient = this.gradient;
  811. var width = options.width || 20;
  812. var height = options.height || 180;
  813. var canvas = new Canvas(width, height);
  814. var paletteCtx = canvas.getContext('2d');
  815. var lineGradient = paletteCtx.createLinearGradient(0, height, 0, 0);
  816. for (var key in gradient) {
  817. lineGradient.addColorStop(parseFloat(key), gradient[key]);
  818. }
  819. paletteCtx.fillStyle = lineGradient;
  820. paletteCtx.fillRect(0, 0, width, height);
  821. return canvas;
  822. };
  823. var global$1 = typeof window === 'undefined' ? {} : window;
  824. var devicePixelRatio = global$1.devicePixelRatio || 1;
  825. /**
  826. * @author kyle / http://nikai.us/
  827. */
  828. function createCircle(size) {
  829. var shadowBlur = size / 2;
  830. var r2 = size + shadowBlur;
  831. var offsetDistance = 10000;
  832. var circle = new Canvas(r2 * 2, r2 * 2);
  833. var context = circle.getContext('2d');
  834. context.shadowBlur = shadowBlur;
  835. context.shadowColor = 'black';
  836. context.shadowOffsetX = context.shadowOffsetY = offsetDistance;
  837. // alert("createCircle");
  838. context.beginPath();
  839. context.arc(r2 - offsetDistance, r2 - offsetDistance, size, 0, Math.PI * 2, true);
  840. context.closePath();
  841. context.fill();
  842. return circle;
  843. }
  844. function colorize(pixels, gradient, options) {
  845. var max = getMax(options);
  846. var min = getMin(options);
  847. var diff = max - min;
  848. var range = options.range || null;
  849. var jMin = 0;
  850. var jMax = 1024;
  851. if (range && range.length === 2) {
  852. jMin = (range[0] - min) / diff * 1024;
  853. }
  854. if (range && range.length === 2) {
  855. jMax = (range[1] - min) / diff * 1024;
  856. }
  857. var maxOpacity = options.maxOpacity || 0.8;
  858. var minOpacity = options.minOpacity || 0;
  859. var range = options.range;
  860. for (var i = 3, len = pixels.length, j; i < len; i += 4) {
  861. j = pixels[i] * 4; // get gradient color from opacity value
  862. if (pixels[i] / 256 > maxOpacity) {
  863. pixels[i] = 256 * maxOpacity;
  864. }
  865. if (pixels[i] / 256 < minOpacity) {
  866. pixels[i] = 256 * minOpacity;
  867. }
  868. if (j && j >= jMin && j <= jMax) {
  869. pixels[i - 3] = gradient[j];
  870. pixels[i - 2] = gradient[j + 1];
  871. pixels[i - 1] = gradient[j + 2];
  872. } else {
  873. pixels[i] = 0;
  874. }
  875. }
  876. }
  877. function getMax(options) {
  878. var max = options.max || 100;
  879. return max;
  880. }
  881. function getMin(options) {
  882. var min = options.min || 0;
  883. return min;
  884. }
  885. function drawGray(context, dataSet, options) {
  886. // alert("drawGray");
  887. var max = getMax(options);
  888. var min = getMin(options);
  889. // console.log(max)
  890. var size = options._size;
  891. if (size == undefined) {
  892. size = options.size;
  893. if (size == undefined) {
  894. size = 13;
  895. }
  896. }
  897. var intensity = new Intensity({
  898. gradient: options.gradient,
  899. max: max,
  900. min: min
  901. });
  902. var circle = createCircle(size);
  903. var circleHalfWidth = circle.width / 2;
  904. var circleHalfHeight = circle.height / 2;
  905. var data = dataSet;
  906. var dataOrderByAlpha = {};
  907. data.forEach(function (item, index) {
  908. var count = item.count === undefined ? 1 : item.count;
  909. var alpha = Math.min(1, count / max).toFixed(2);
  910. dataOrderByAlpha[alpha] = dataOrderByAlpha[alpha] || [];
  911. dataOrderByAlpha[alpha].push(item);
  912. });
  913. for (var i in dataOrderByAlpha) {
  914. if (isNaN(i)) continue;
  915. var _data = dataOrderByAlpha[i];
  916. context.beginPath();
  917. if (!options.withoutAlpha) {
  918. context.globalAlpha = i;
  919. }
  920. context.strokeStyle = intensity.getColor(i * max);
  921. _data.forEach(function (item, index) {
  922. if (!item.geometry) {
  923. return;
  924. }
  925. var coordinates = item.geometry._coordinates || item.geometry.coordinates;
  926. var type = item.geometry.type;
  927. if (type === 'Point') {
  928. var count = item.count === undefined ? 1 : item.count;
  929. context.globalAlpha = count / max;
  930. context.drawImage(circle, coordinates[0] - circleHalfWidth, coordinates[1] - circleHalfHeight);
  931. } else if (type === 'LineString') {
  932. var count = item.count === undefined ? 1 : item.count;
  933. context.globalAlpha = count / max;
  934. context.beginPath();
  935. pathSimple.draw(context, item, options);
  936. context.stroke();
  937. } else if (type === 'Polygon') {}
  938. });
  939. }
  940. }
  941. function draw$1(context, dataSet, options) {
  942. if (context.canvas.width <= 0 || context.canvas.height <= 0) {
  943. return;
  944. }
  945. // alert("draw$1");
  946. var strength = options.strength || 0.3;
  947. context.strokeStyle = 'rgba(0,0,0,' + strength + ')';
  948. var shadowCanvas = new Canvas(context.canvas.width, context.canvas.height);
  949. var shadowContext = shadowCanvas.getContext('2d');
  950. shadowContext.scale(devicePixelRatio, devicePixelRatio);
  951. options = options || {};
  952. var data = dataSet instanceof DataSet ? dataSet.get() : dataSet;
  953. context.save();
  954. var intensity = new Intensity({
  955. gradient: options.gradient
  956. });
  957. //console.time('drawGray')
  958. drawGray(shadowContext, data, options);
  959. //console.timeEnd('drawGray');
  960. // return false;
  961. if (!options.absolute) {
  962. //console.time('changeColor');
  963. var colored = shadowContext.getImageData(0, 0, context.canvas.width, context.canvas.height);
  964. colorize(colored.data, intensity.getImageData(), options);
  965. //console.timeEnd('changeColor');
  966. context.putImageData(colored, 0, 0);
  967. context.restore();
  968. }
  969. intensity = null;
  970. shadowCanvas = null;
  971. }
  972. var drawHeatmap = {
  973. draw: draw$1
  974. };
  975. /**
  976. * @author kyle / http://nikai.us/
  977. */
  978. var drawGrid = {
  979. draw: function draw(context, dataSet, options) {
  980. // alert("drawGrid");
  981. context.save();
  982. var data = dataSet instanceof DataSet ? dataSet.get() : dataSet;
  983. var grids = {};
  984. var size = options._size || options.size || 50;
  985. // 后端传入数据为网格数据时,传入enableCluster为false,前端不进行删格化操作,直接画方格
  986. var enableCluster = 'enableCluster' in options ? options.enableCluster : true;
  987. var offset = options.offset || {
  988. x: 0,
  989. y: 0
  990. };
  991. var intensity = new Intensity({
  992. min: options.min || 0,
  993. max: options.max || 100,
  994. gradient: options.gradient
  995. });
  996. if (!enableCluster) {
  997. for (var i = 0; i < data.length; i++) {
  998. var coordinates = data[i].geometry._coordinates || data[i].geometry.coordinates;
  999. var gridKey = coordinates.join(',');
  1000. grids[gridKey] = data[i].count || 1;
  1001. }
  1002. for (var _gridKey in grids) {
  1003. _gridKey = _gridKey.split(',');
  1004. context.beginPath();
  1005. context.rect(+_gridKey[0] - size / 2, +_gridKey[1] - size / 2, size, size);
  1006. context.fillStyle = intensity.getColor(grids[_gridKey]);
  1007. context.fill();
  1008. if (options.strokeStyle && options.lineWidth) {
  1009. context.stroke();
  1010. }
  1011. }
  1012. } else {
  1013. for (var _i = 0; _i < data.length; _i++) {
  1014. var coordinates = data[_i].geometry._coordinates || data[_i].geometry.coordinates;
  1015. var gridKey = Math.floor((coordinates[0] - offset.x) / size) + ',' + Math.floor((coordinates[1] - offset.y) / size);
  1016. if (!grids[gridKey]) {
  1017. grids[gridKey] = 0;
  1018. }
  1019. grids[gridKey] += ~~(data[_i].count || 1);
  1020. }
  1021. for (var _gridKey2 in grids) {
  1022. _gridKey2 = _gridKey2.split(',');
  1023. context.beginPath();
  1024. context.rect(_gridKey2[0] * size + .5 + offset.x, _gridKey2[1] * size + .5 + offset.y, size, size);
  1025. context.fillStyle = intensity.getColor(grids[_gridKey2]);
  1026. context.fill();
  1027. if (options.strokeStyle && options.lineWidth) {
  1028. context.stroke();
  1029. }
  1030. }
  1031. }
  1032. if (options.label && options.label.show !== false) {
  1033. context.fillStyle = options.label.fillStyle || 'white';
  1034. if (options.label.font) {
  1035. context.font = options.label.font;
  1036. }
  1037. if (options.label.shadowColor) {
  1038. context.shadowColor = options.label.shadowColor;
  1039. }
  1040. if (options.label.shadowBlur) {
  1041. context.shadowBlur = options.label.shadowBlur;
  1042. }
  1043. for (var gridKey in grids) {
  1044. gridKey = gridKey.split(',');
  1045. var text = grids[gridKey];
  1046. var textWidth = context.measureText(text).width;
  1047. if (!enableCluster) {
  1048. context.fillText(text, +gridKey[0] - textWidth / 2, +gridKey[1] + 5);
  1049. } else {
  1050. context.fillText(text, gridKey[0] * size + .5 + offset.x + size / 2 - textWidth / 2, gridKey[1] * size + .5 + offset.y + size / 2 + 5);
  1051. }
  1052. }
  1053. }
  1054. context.restore();
  1055. }
  1056. };
  1057. /**
  1058. * @author kyle / http://nikai.us/
  1059. */
  1060. function hex_corner$1(center, size, i) {
  1061. var angle_deg = 60 * i + 30;
  1062. var angle_rad = Math.PI / 180 * angle_deg;
  1063. return [center.x + size * Math.cos(angle_rad), center.y + size * Math.sin(angle_rad)];
  1064. }
  1065. var drawHoneycomb = {
  1066. draw: function draw(context, dataSet, options) {
  1067. // alert("drawHoneycomb");
  1068. context.save();
  1069. var data = dataSet instanceof DataSet ? dataSet.get() : dataSet;
  1070. for (var key in options) {
  1071. context[key] = options[key];
  1072. }
  1073. var grids = {};
  1074. var offset = options.offset || {
  1075. x: 10,
  1076. y: 10
  1077. };
  1078. var r = options._size || options.size || 40;
  1079. r = r / 2 / Math.sin(Math.PI / 3);
  1080. var dx = r * 2 * Math.sin(Math.PI / 3);
  1081. var dy = r * 1.5;
  1082. var binsById = {};
  1083. for (var i = 0; i < data.length; i++) {
  1084. var coordinates = data[i].geometry._coordinates || data[i].geometry.coordinates;
  1085. var py = (coordinates[1] - offset.y) / dy,
  1086. pj = Math.round(py),
  1087. px = (coordinates[0] - offset.x) / dx - (pj & 1 ? .5 : 0),
  1088. pi = Math.round(px),
  1089. py1 = py - pj;
  1090. if (Math.abs(py1) * 3 > 1) {
  1091. var px1 = px - pi,
  1092. pi2 = pi + (px < pi ? -1 : 1) / 2,
  1093. pj2 = pj + (py < pj ? -1 : 1),
  1094. px2 = px - pi2,
  1095. py2 = py - pj2;
  1096. if (px1 * px1 + py1 * py1 > px2 * px2 + py2 * py2) pi = pi2 + (pj & 1 ? 1 : -1) / 2, pj = pj2;
  1097. }
  1098. var id = pi + "-" + pj,
  1099. bin = binsById[id];
  1100. if (bin) {
  1101. bin.push(data[i]);
  1102. } else {
  1103. bin = binsById[id] = [data[i]];
  1104. bin.i = pi;
  1105. bin.j = pj;
  1106. bin.x = (pi + (pj & 1 ? 1 / 2 : 0)) * dx;
  1107. bin.y = pj * dy;
  1108. }
  1109. }
  1110. var intensity = new Intensity({
  1111. max: options.max || 100,
  1112. maxSize: r,
  1113. gradient: options.gradient
  1114. });
  1115. for (var key in binsById) {
  1116. var item = binsById[key];
  1117. context.beginPath();
  1118. for (var j = 0; j < 6; j++) {
  1119. var result = hex_corner$1({
  1120. x: item.x + offset.x,
  1121. y: item.y + offset.y
  1122. }, r, j);
  1123. context.lineTo(result[0], result[1]);
  1124. }
  1125. context.closePath();
  1126. var count = 0;
  1127. for (var i = 0; i < item.length; i++) {
  1128. count += item[i].count || 1;
  1129. }
  1130. item.count = count;
  1131. context.fillStyle = intensity.getColor(count);
  1132. context.fill();
  1133. if (options.strokeStyle && options.lineWidth) {
  1134. context.stroke();
  1135. }
  1136. }
  1137. if (options.label && options.label.show !== false) {
  1138. context.fillStyle = options.label.fillStyle || 'white';
  1139. if (options.label.font) {
  1140. context.font = options.label.font;
  1141. }
  1142. if (options.label.shadowColor) {
  1143. context.shadowColor = options.label.shadowColor;
  1144. }
  1145. if (options.label.shadowBlur) {
  1146. context.shadowBlur = options.label.shadowBlur;
  1147. }
  1148. for (var key in binsById) {
  1149. var item = binsById[key];
  1150. var text = item.count;
  1151. if (text < 0) {
  1152. text = text.toFixed(2);
  1153. } else {
  1154. text = ~~text;
  1155. }
  1156. var textWidth = context.measureText(text).width;
  1157. context.fillText(text, item.x + offset.x - textWidth / 2, item.y + offset.y + 5);
  1158. }
  1159. }
  1160. context.restore();
  1161. }
  1162. };
  1163. function createShader(gl, src, type) {
  1164. var shader = gl.createShader(type);
  1165. gl.shaderSource(shader, src);
  1166. gl.compileShader(shader);
  1167. return shader;
  1168. }
  1169. function initShaders(gl, vs_source, fs_source) {
  1170. var vertexShader = createShader(gl, vs_source, gl.VERTEX_SHADER);
  1171. var fragmentShader = createShader(gl, fs_source, gl.FRAGMENT_SHADER);
  1172. var glProgram = gl.createProgram();
  1173. gl.attachShader(glProgram, vertexShader);
  1174. gl.attachShader(glProgram, fragmentShader);
  1175. gl.linkProgram(glProgram);
  1176. gl.useProgram(glProgram);
  1177. return glProgram;
  1178. }
  1179. function getColorData(color) {
  1180. var tmpCanvas = document.createElement('canvas');
  1181. var tmpCtx = tmpCanvas.getContext('2d');
  1182. tmpCanvas.width = 1;
  1183. tmpCanvas.height = 1;
  1184. tmpCtx.fillStyle = color;
  1185. tmpCtx.fillRect(0, 0, 1, 1);
  1186. return tmpCtx.getImageData(0, 0, 1, 1).data;
  1187. }
  1188. var vs_s = ['attribute vec4 a_Position;', 'void main() {', 'gl_Position = a_Position;', 'gl_PointSize = 30.0;', '}'].join('');
  1189. var fs_s = ['precision mediump float;', 'uniform vec4 u_FragColor;', 'void main() {', 'gl_FragColor = u_FragColor;', '}'].join('');
  1190. function draw$2(gl, data, options) {
  1191. if (!data) {
  1192. return;
  1193. }
  1194. // alert("draw$2");
  1195. var program = initShaders(gl, vs_s, fs_s);
  1196. gl.enable(gl.BLEND);
  1197. gl.blendFunc(gl.SRC_ALPHA, gl.ONE);
  1198. //gl.clearColor(0.0, 0.0, 1.0, 1.0);
  1199. gl.clear(gl.COLOR_BUFFER_BIT);
  1200. var halfCanvasWidth = gl.canvas.width / 2;
  1201. var halfCanvasHeight = gl.canvas.height / 2;
  1202. // Create a buffer object
  1203. var vertexBuffer = gl.createBuffer();
  1204. // Bind the buffer object to target
  1205. gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer);
  1206. var a_Position = gl.getAttribLocation(program, 'a_Position');
  1207. // Assign the buffer object to a_Position variable
  1208. gl.vertexAttribPointer(a_Position, 2, gl.FLOAT, false, 0, 0);
  1209. // Enable the assignment to a_Position variable
  1210. gl.enableVertexAttribArray(a_Position);
  1211. var uFragColor = gl.getUniformLocation(program, 'u_FragColor');
  1212. var colored = getColorData(options.strokeStyle || 'red');
  1213. gl.uniform4f(uFragColor, colored[0] / 255, colored[1] / 255, colored[2] / 255, colored[3] / 255);
  1214. gl.lineWidth(options.lineWidth || 1);
  1215. for (var i = 0, len = data.length; i < len; i++) {
  1216. var _geometry = data[i].geometry._coordinates;
  1217. var verticesData = [];
  1218. for (var j = 0; j < _geometry.length; j++) {
  1219. var item = _geometry[j];
  1220. var x = (item[0] - halfCanvasWidth) / halfCanvasWidth;
  1221. var y = (halfCanvasHeight - item[1]) / halfCanvasHeight;
  1222. verticesData.push(x, y);
  1223. }
  1224. var vertices = new Float32Array(verticesData);
  1225. // Write date into the buffer object
  1226. gl.bufferData(gl.ARRAY_BUFFER, vertices, gl.STATIC_DRAW);
  1227. gl.drawArrays(gl.LINE_STRIP, 0, _geometry.length);
  1228. }
  1229. }
  1230. var line = {
  1231. draw: draw$2
  1232. };
  1233. var vs_s$1 = ['attribute vec4 a_Position;', 'attribute float a_PointSize;', 'void main() {', 'gl_Position = a_Position;', 'gl_PointSize = a_PointSize;', '}'].join('');
  1234. var fs_s$1 = ['precision mediump float;', 'uniform vec4 u_FragColor;', 'void main() {', 'gl_FragColor = u_FragColor;', '}'].join('');
  1235. function draw$3(gl, data, options) {
  1236. if (!data) {
  1237. return;
  1238. }
  1239. // alert("draw$3");
  1240. var program = initShaders(gl, vs_s$1, fs_s$1);
  1241. var a_Position = gl.getAttribLocation(program, 'a_Position');
  1242. var a_PointSize = gl.getAttribLocation(program, 'a_PointSize');
  1243. var uFragColor = gl.getUniformLocation(program, 'u_FragColor');
  1244. //gl.clearColor(0.0, 0.0, 1.0, 1.0);
  1245. gl.clear(gl.COLOR_BUFFER_BIT);
  1246. var halfCanvasWidth = gl.canvas.width / 2;
  1247. var halfCanvasHeight = gl.canvas.height / 2;
  1248. var verticesData = [];
  1249. var count = 0;
  1250. for (var i = 0; i < data.length; i++) {
  1251. var item = data[i].geometry._coordinates;
  1252. var x = (item[0] - halfCanvasWidth) / halfCanvasWidth;
  1253. var y = (halfCanvasHeight - item[1]) / halfCanvasHeight;
  1254. if (x < -1 || x > 1 || y < -1 || y > 1) {
  1255. continue;
  1256. }
  1257. verticesData.push(x, y);
  1258. count++;
  1259. }
  1260. var vertices = new Float32Array(verticesData);
  1261. var n = count; // The number of vertices
  1262. // Create a buffer object
  1263. var vertexBuffer = gl.createBuffer();
  1264. // Bind the buffer object to target
  1265. gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer);
  1266. // Write date into the buffer object
  1267. gl.bufferData(gl.ARRAY_BUFFER, vertices, gl.STATIC_DRAW);
  1268. // Assign the buffer object to a_Position variable
  1269. gl.vertexAttribPointer(a_Position, 2, gl.FLOAT, false, 0, 0);
  1270. // Enable the assignment to a_Position variable
  1271. gl.enableVertexAttribArray(a_Position);
  1272. gl.vertexAttrib1f(a_PointSize, options._size);
  1273. var colored = getColorData(options.fillStyle || 'red');
  1274. gl.uniform4f(uFragColor, colored[0] / 255, colored[1] / 255, colored[2] / 255, colored[3] / 255);
  1275. gl.drawArrays(gl.POINTS, 0, n);
  1276. }
  1277. var point = {
  1278. draw: draw$3
  1279. };
  1280. function earcut(data, holeIndices, dim) {
  1281. dim = dim || 2;
  1282. var hasHoles = holeIndices && holeIndices.length,
  1283. outerLen = hasHoles ? holeIndices[0] * dim : data.length,
  1284. outerNode = linkedList(data, 0, outerLen, dim, true),
  1285. triangles = [];
  1286. if (!outerNode) return triangles;
  1287. var minX, minY, maxX, maxY, x, y, size;
  1288. if (hasHoles) outerNode = eliminateHoles(data, holeIndices, outerNode, dim);
  1289. // if the shape is not too simple, we'll use z-order curve hash later; calculate polygon bbox
  1290. if (data.length > 80 * dim) {
  1291. minX = maxX = data[0];
  1292. minY = maxY = data[1];
  1293. for (var i = dim; i < outerLen; i += dim) {
  1294. x = data[i];
  1295. y = data[i + 1];
  1296. if (x < minX) minX = x;
  1297. if (y < minY) minY = y;
  1298. if (x > maxX) maxX = x;
  1299. if (y > maxY) maxY = y;
  1300. }
  1301. // minX, minY and size are later used to transform coords into integers for z-order calculation
  1302. size = Math.max(maxX - minX, maxY - minY);
  1303. }
  1304. earcutLinked(outerNode, triangles, dim, minX, minY, size);
  1305. return triangles;
  1306. }
  1307. // create a circular doubly linked list from polygon points in the specified winding order
  1308. function linkedList(data, start, end, dim, clockwise) {
  1309. var i, last;
  1310. if (clockwise === signedArea(data, start, end, dim) > 0) {
  1311. for (i = start; i < end; i += dim) {
  1312. last = insertNode(i, data[i], data[i + 1], last);
  1313. }
  1314. } else {
  1315. for (i = end - dim; i >= start; i -= dim) {
  1316. last = insertNode(i, data[i], data[i + 1], last);
  1317. }
  1318. }
  1319. if (last && equals(last, last.next)) {
  1320. removeNode(last);
  1321. last = last.next;
  1322. }
  1323. return last;
  1324. }
  1325. // eliminate colinear or duplicate points
  1326. function filterPoints(start, end) {
  1327. if (!start) return start;
  1328. if (!end) end = start;
  1329. var p = start,
  1330. again;
  1331. do {
  1332. again = false;
  1333. if (!p.steiner && (equals(p, p.next) || area(p.prev, p, p.next) === 0)) {
  1334. removeNode(p);
  1335. p = end = p.prev;
  1336. if (p === p.next) return null;
  1337. again = true;
  1338. } else {
  1339. p = p.next;
  1340. }
  1341. } while (again || p !== end);
  1342. return end;
  1343. }
  1344. // main ear slicing loop which triangulates a polygon (given as a linked list)
  1345. function earcutLinked(ear, triangles, dim, minX, minY, size, pass) {
  1346. if (!ear) return;
  1347. // interlink polygon nodes in z-order
  1348. if (!pass && size) indexCurve(ear, minX, minY, size);
  1349. var stop = ear,
  1350. prev,
  1351. next;
  1352. // iterate through ears, slicing them one by one
  1353. while (ear.prev !== ear.next) {
  1354. prev = ear.prev;
  1355. next = ear.next;
  1356. if (size ? isEarHashed(ear, minX, minY, size) : isEar(ear)) {
  1357. // cut off the triangle
  1358. triangles.push(prev.i / dim);
  1359. triangles.push(ear.i / dim);
  1360. triangles.push(next.i / dim);
  1361. removeNode(ear);
  1362. // skipping the next vertice leads to less sliver triangles
  1363. ear = next.next;
  1364. stop = next.next;
  1365. continue;
  1366. }
  1367. ear = next;
  1368. // if we looped through the whole remaining polygon and can't find any more ears
  1369. if (ear === stop) {
  1370. // try filtering points and slicing again
  1371. if (!pass) {
  1372. earcutLinked(filterPoints(ear), triangles, dim, minX, minY, size, 1);
  1373. // if this didn't work, try curing all small self-intersections locally
  1374. } else if (pass === 1) {
  1375. ear = cureLocalIntersections(ear, triangles, dim);
  1376. earcutLinked(ear, triangles, dim, minX, minY, size, 2);
  1377. // as a last resort, try splitting the remaining polygon into two
  1378. } else if (pass === 2) {
  1379. splitEarcut(ear, triangles, dim, minX, minY, size);
  1380. }
  1381. break;
  1382. }
  1383. }
  1384. }
  1385. // check whether a polygon node forms a valid ear with adjacent nodes
  1386. function isEar(ear) {
  1387. var a = ear.prev,
  1388. b = ear,
  1389. c = ear.next;
  1390. if (area(a, b, c) >= 0) return false; // reflex, can't be an ear
  1391. // now make sure we don't have other points inside the potential ear
  1392. var p = ear.next.next;
  1393. while (p !== ear.prev) {
  1394. if (pointInTriangle(a.x, a.y, b.x, b.y, c.x, c.y, p.x, p.y) && area(p.prev, p, p.next) >= 0) return false;
  1395. p = p.next;
  1396. }
  1397. return true;
  1398. }
  1399. function isEarHashed(ear, minX, minY, size) {
  1400. var a = ear.prev,
  1401. b = ear,
  1402. c = ear.next;
  1403. if (area(a, b, c) >= 0) return false; // reflex, can't be an ear
  1404. // triangle bbox; min & max are calculated like this for speed
  1405. var minTX = a.x < b.x ? a.x < c.x ? a.x : c.x : b.x < c.x ? b.x : c.x,
  1406. minTY = a.y < b.y ? a.y < c.y ? a.y : c.y : b.y < c.y ? b.y : c.y,
  1407. maxTX = a.x > b.x ? a.x > c.x ? a.x : c.x : b.x > c.x ? b.x : c.x,
  1408. maxTY = a.y > b.y ? a.y > c.y ? a.y : c.y : b.y > c.y ? b.y : c.y;
  1409. // z-order range for the current triangle bbox;
  1410. var minZ = zOrder(minTX, minTY, minX, minY, size),
  1411. maxZ = zOrder(maxTX, maxTY, minX, minY, size);
  1412. // first look for points inside the triangle in increasing z-order
  1413. var p = ear.nextZ;
  1414. while (p && p.z <= maxZ) {
  1415. if (p !== ear.prev && p !== ear.next && pointInTriangle(a.x, a.y, b.x, b.y, c.x, c.y, p.x, p.y) && area(p.prev, p, p.next) >= 0) return false;
  1416. p = p.nextZ;
  1417. }
  1418. // then look for points in decreasing z-order
  1419. p = ear.prevZ;
  1420. while (p && p.z >= minZ) {
  1421. if (p !== ear.prev && p !== ear.next && pointInTriangle(a.x, a.y, b.x, b.y, c.x, c.y, p.x, p.y) && area(p.prev, p, p.next) >= 0) return false;
  1422. p = p.prevZ;
  1423. }
  1424. return true;
  1425. }
  1426. // go through all polygon nodes and cure small local self-intersections
  1427. function cureLocalIntersections(start, triangles, dim) {
  1428. var p = start;
  1429. do {
  1430. var a = p.prev,
  1431. b = p.next.next;
  1432. if (!equals(a, b) && intersects(a, p, p.next, b) && locallyInside(a, b) && locallyInside(b, a)) {
  1433. triangles.push(a.i / dim);
  1434. triangles.push(p.i / dim);
  1435. triangles.push(b.i / dim);
  1436. // remove two nodes involved
  1437. removeNode(p);
  1438. removeNode(p.next);
  1439. p = start = b;
  1440. }
  1441. p = p.next;
  1442. } while (p !== start);
  1443. return p;
  1444. }
  1445. // try splitting polygon into two and triangulate them independently
  1446. function splitEarcut(start, triangles, dim, minX, minY, size) {
  1447. // look for a valid diagonal that divides the polygon into two
  1448. var a = start;
  1449. do {
  1450. var b = a.next.next;
  1451. while (b !== a.prev) {
  1452. if (a.i !== b.i && isValidDiagonal(a, b)) {
  1453. // split the polygon in two by the diagonal
  1454. var c = splitPolygon(a, b);
  1455. // filter colinear points around the cuts
  1456. a = filterPoints(a, a.next);
  1457. c = filterPoints(c, c.next);
  1458. // run earcut on each half
  1459. earcutLinked(a, triangles, dim, minX, minY, size);
  1460. earcutLinked(c, triangles, dim, minX, minY, size);
  1461. return;
  1462. }
  1463. b = b.next;
  1464. }
  1465. a = a.next;
  1466. } while (a !== start);
  1467. }
  1468. // link every hole into the outer loop, producing a single-ring polygon without holes
  1469. function eliminateHoles(data, holeIndices, outerNode, dim) {
  1470. var queue = [],
  1471. i,
  1472. len,
  1473. start,
  1474. end,
  1475. list;
  1476. for (i = 0, len = holeIndices.length; i < len; i++) {
  1477. start = holeIndices[i] * dim;
  1478. end = i < len - 1 ? holeIndices[i + 1] * dim : data.length;
  1479. list = linkedList(data, start, end, dim, false);
  1480. if (list === list.next) list.steiner = true;
  1481. queue.push(getLeftmost(list));
  1482. }
  1483. queue.sort(compareX);
  1484. // process holes from left to right
  1485. for (i = 0; i < queue.length; i++) {
  1486. eliminateHole(queue[i], outerNode);
  1487. outerNode = filterPoints(outerNode, outerNode.next);
  1488. }
  1489. return outerNode;
  1490. }
  1491. function compareX(a, b) {
  1492. return a.x - b.x;
  1493. }
  1494. // find a bridge between vertices that connects hole with an outer ring and and link it
  1495. function eliminateHole(hole, outerNode) {
  1496. outerNode = findHoleBridge(hole, outerNode);
  1497. if (outerNode) {
  1498. var b = splitPolygon(outerNode, hole);
  1499. filterPoints(b, b.next);
  1500. }
  1501. }
  1502. // David Eberly's algorithm for finding a bridge between hole and outer polygon
  1503. function findHoleBridge(hole, outerNode) {
  1504. var p = outerNode,
  1505. hx = hole.x,
  1506. hy = hole.y,
  1507. qx = -Infinity,
  1508. m;
  1509. // find a segment intersected by a ray from the hole's leftmost point to the left;
  1510. // segment's endpoint with lesser x will be potential connection point
  1511. do {
  1512. if (hy <= p.y && hy >= p.next.y) {
  1513. var x = p.x + (hy - p.y) * (p.next.x - p.x) / (p.next.y - p.y);
  1514. if (x <= hx && x > qx) {
  1515. qx = x;
  1516. if (x === hx) {
  1517. if (hy === p.y) return p;
  1518. if (hy === p.next.y) return p.next;
  1519. }
  1520. m = p.x < p.next.x ? p : p.next;
  1521. }
  1522. }
  1523. p = p.next;
  1524. } while (p !== outerNode);
  1525. if (!m) return null;
  1526. if (hx === qx) return m.prev; // hole touches outer segment; pick lower endpoint
  1527. // look for points inside the triangle of hole point, segment intersection and endpoint;
  1528. // if there are no points found, we have a valid connection;
  1529. // otherwise choose the point of the minimum angle with the ray as connection point
  1530. var stop = m,
  1531. mx = m.x,
  1532. my = m.y,
  1533. tanMin = Infinity,
  1534. tan;
  1535. p = m.next;
  1536. while (p !== stop) {
  1537. if (hx >= p.x && p.x >= mx && pointInTriangle(hy < my ? hx : qx, hy, mx, my, hy < my ? qx : hx, hy, p.x, p.y)) {
  1538. tan = Math.abs(hy - p.y) / (hx - p.x); // tangential
  1539. if ((tan < tanMin || tan === tanMin && p.x > m.x) && locallyInside(p, hole)) {
  1540. m = p;
  1541. tanMin = tan;
  1542. }
  1543. }
  1544. p = p.next;
  1545. }
  1546. return m;
  1547. }
  1548. // interlink polygon nodes in z-order
  1549. function indexCurve(start, minX, minY, size) {
  1550. var p = start;
  1551. do {
  1552. if (p.z === null) p.z = zOrder(p.x, p.y, minX, minY, size);
  1553. p.prevZ = p.prev;
  1554. p.nextZ = p.next;
  1555. p = p.next;
  1556. } while (p !== start);
  1557. p.prevZ.nextZ = null;
  1558. p.prevZ = null;
  1559. sortLinked(p);
  1560. }
  1561. // Simon Tatham's linked list merge sort algorithm
  1562. // http://www.chiark.greenend.org.uk/~sgtatham/algorithms/listsort.html
  1563. function sortLinked(list) {
  1564. var i,
  1565. p,
  1566. q,
  1567. e,
  1568. tail,
  1569. numMerges,
  1570. pSize,
  1571. qSize,
  1572. inSize = 1;
  1573. do {
  1574. p = list;
  1575. list = null;
  1576. tail = null;
  1577. numMerges = 0;
  1578. while (p) {
  1579. numMerges++;
  1580. q = p;
  1581. pSize = 0;
  1582. for (i = 0; i < inSize; i++) {
  1583. pSize++;
  1584. q = q.nextZ;
  1585. if (!q) break;
  1586. }
  1587. qSize = inSize;
  1588. while (pSize > 0 || qSize > 0 && q) {
  1589. if (pSize === 0) {
  1590. e = q;
  1591. q = q.nextZ;
  1592. qSize--;
  1593. } else if (qSize === 0 || !q) {
  1594. e = p;
  1595. p = p.nextZ;
  1596. pSize--;
  1597. } else if (p.z <= q.z) {
  1598. e = p;
  1599. p = p.nextZ;
  1600. pSize--;
  1601. } else {
  1602. e = q;
  1603. q = q.nextZ;
  1604. qSize--;
  1605. }
  1606. if (tail) tail.nextZ = e;else list = e;
  1607. e.prevZ = tail;
  1608. tail = e;
  1609. }
  1610. p = q;
  1611. }
  1612. tail.nextZ = null;
  1613. inSize *= 2;
  1614. } while (numMerges > 1);
  1615. return list;
  1616. }
  1617. // z-order of a point given coords and size of the data bounding box
  1618. function zOrder(x, y, minX, minY, size) {
  1619. // coords are transformed into non-negative 15-bit integer range
  1620. x = 32767 * (x - minX) / size;
  1621. y = 32767 * (y - minY) / size;
  1622. x = (x | x << 8) & 0x00FF00FF;
  1623. x = (x | x << 4) & 0x0F0F0F0F;
  1624. x = (x | x << 2) & 0x33333333;
  1625. x = (x | x << 1) & 0x55555555;
  1626. y = (y | y << 8) & 0x00FF00FF;
  1627. y = (y | y << 4) & 0x0F0F0F0F;
  1628. y = (y | y << 2) & 0x33333333;
  1629. y = (y | y << 1) & 0x55555555;
  1630. return x | y << 1;
  1631. }
  1632. // find the leftmost node of a polygon ring
  1633. function getLeftmost(start) {
  1634. var p = start,
  1635. leftmost = start;
  1636. do {
  1637. if (p.x < leftmost.x) leftmost = p;
  1638. p = p.next;
  1639. } while (p !== start);
  1640. return leftmost;
  1641. }
  1642. // check if a point lies within a convex triangle
  1643. function pointInTriangle(ax, ay, bx, by, cx, cy, px, py) {
  1644. return (cx - px) * (ay - py) - (ax - px) * (cy - py) >= 0 && (ax - px) * (by - py) - (bx - px) * (ay - py) >= 0 && (bx - px) * (cy - py) - (cx - px) * (by - py) >= 0;
  1645. }
  1646. // check if a diagonal between two polygon nodes is valid (lies in polygon interior)
  1647. function isValidDiagonal(a, b) {
  1648. return a.next.i !== b.i && a.prev.i !== b.i && !intersectsPolygon(a, b) && locallyInside(a, b) && locallyInside(b, a) && middleInside(a, b);
  1649. }
  1650. // signed area of a triangle
  1651. function area(p, q, r) {
  1652. return (q.y - p.y) * (r.x - q.x) - (q.x - p.x) * (r.y - q.y);
  1653. }
  1654. // check if two points are equal
  1655. function equals(p1, p2) {
  1656. return p1.x === p2.x && p1.y === p2.y;
  1657. }
  1658. // check if two segments intersect
  1659. function intersects(p1, q1, p2, q2) {
  1660. if (equals(p1, q1) && equals(p2, q2) || equals(p1, q2) && equals(p2, q1)) return true;
  1661. return area(p1, q1, p2) > 0 !== area(p1, q1, q2) > 0 && area(p2, q2, p1) > 0 !== area(p2, q2, q1) > 0;
  1662. }
  1663. // check if a polygon diagonal intersects any polygon segments
  1664. function intersectsPolygon(a, b) {
  1665. var p = a;
  1666. do {
  1667. if (p.i !== a.i && p.next.i !== a.i && p.i !== b.i && p.next.i !== b.i && intersects(p, p.next, a, b)) return true;
  1668. p = p.next;
  1669. } while (p !== a);
  1670. return false;
  1671. }
  1672. // check if a polygon diagonal is locally inside the polygon
  1673. function locallyInside(a, b) {
  1674. return area(a.prev, a, a.next) < 0 ? area(a, b, a.next) >= 0 && area(a, a.prev, b) >= 0 : area(a, b, a.prev) < 0 || area(a, a.next, b) < 0;
  1675. }
  1676. // check if the middle point of a polygon diagonal is inside the polygon
  1677. function middleInside(a, b) {
  1678. var p = a,
  1679. inside = false,
  1680. px = (a.x + b.x) / 2,
  1681. py = (a.y + b.y) / 2;
  1682. do {
  1683. if (p.y > py !== p.next.y > py && px < (p.next.x - p.x) * (py - p.y) / (p.next.y - p.y) + p.x) inside = !inside;
  1684. p = p.next;
  1685. } while (p !== a);
  1686. return inside;
  1687. }
  1688. // link two polygon vertices with a bridge; if the vertices belong to the same ring, it splits polygon into two;
  1689. // if one belongs to the outer ring and another to a hole, it merges it into a single ring
  1690. function splitPolygon(a, b) {
  1691. var a2 = new Node(a.i, a.x, a.y),
  1692. b2 = new Node(b.i, b.x, b.y),
  1693. an = a.next,
  1694. bp = b.prev;
  1695. a.next = b;
  1696. b.prev = a;
  1697. a2.next = an;
  1698. an.prev = a2;
  1699. b2.next = a2;
  1700. a2.prev = b2;
  1701. bp.next = b2;
  1702. b2.prev = bp;
  1703. return b2;
  1704. }
  1705. // create a node and optionally link it with previous one (in a circular doubly linked list)
  1706. function insertNode(i, x, y, last) {
  1707. var p = new Node(i, x, y);
  1708. if (!last) {
  1709. p.prev = p;
  1710. p.next = p;
  1711. } else {
  1712. p.next = last.next;
  1713. p.prev = last;
  1714. last.next.prev = p;
  1715. last.next = p;
  1716. }
  1717. return p;
  1718. }
  1719. function removeNode(p) {
  1720. p.next.prev = p.prev;
  1721. p.prev.next = p.next;
  1722. if (p.prevZ) p.prevZ.nextZ = p.nextZ;
  1723. if (p.nextZ) p.nextZ.prevZ = p.prevZ;
  1724. }
  1725. function Node(i, x, y) {
  1726. // vertice index in coordinates array
  1727. this.i = i;
  1728. // vertex coordinates
  1729. this.x = x;
  1730. this.y = y;
  1731. // previous and next vertice nodes in a polygon ring
  1732. this.prev = null;
  1733. this.next = null;
  1734. // z-order curve value
  1735. this.z = null;
  1736. // previous and next nodes in z-order
  1737. this.prevZ = null;
  1738. this.nextZ = null;
  1739. // indicates whether this is a steiner point
  1740. this.steiner = false;
  1741. }
  1742. // return a percentage difference between the polygon area and its triangulation area;
  1743. // used to verify correctness of triangulation
  1744. earcut.deviation = function (data, holeIndices, dim, triangles) {
  1745. var hasHoles = holeIndices && holeIndices.length;
  1746. var outerLen = hasHoles ? holeIndices[0] * dim : data.length;
  1747. var polygonArea = Math.abs(signedArea(data, 0, outerLen, dim));
  1748. if (hasHoles) {
  1749. for (var i = 0, len = holeIndices.length; i < len; i++) {
  1750. var start = holeIndices[i] * dim;
  1751. var end = i < len - 1 ? holeIndices[i + 1] * dim : data.length;
  1752. polygonArea -= Math.abs(signedArea(data, start, end, dim));
  1753. }
  1754. }
  1755. var trianglesArea = 0;
  1756. for (i = 0; i < triangles.length; i += 3) {
  1757. var a = triangles[i] * dim;
  1758. var b = triangles[i + 1] * dim;
  1759. var c = triangles[i + 2] * dim;
  1760. trianglesArea += Math.abs((data[a] - data[c]) * (data[b + 1] - data[a + 1]) - (data[a] - data[b]) * (data[c + 1] - data[a + 1]));
  1761. }
  1762. return polygonArea === 0 && trianglesArea === 0 ? 0 : Math.abs((trianglesArea - polygonArea) / polygonArea);
  1763. };
  1764. function signedArea(data, start, end, dim) {
  1765. var sum = 0;
  1766. for (var i = start, j = end - dim; i < end; i += dim) {
  1767. sum += (data[j] - data[i]) * (data[i + 1] + data[j + 1]);
  1768. j = i;
  1769. }
  1770. return sum;
  1771. }
  1772. // turn a polygon in a multi-dimensional array form (e.g. as in GeoJSON) into a form Earcut accepts
  1773. earcut.flatten = function (data) {
  1774. var dim = data[0][0].length,
  1775. result = { vertices: [], holes: [], dimensions: dim },
  1776. holeIndex = 0;
  1777. for (var i = 0; i < data.length; i++) {
  1778. for (var j = 0; j < data[i].length; j++) {
  1779. for (var d = 0; d < dim; d++) {
  1780. result.vertices.push(data[i][j][d]);
  1781. }
  1782. }
  1783. if (i > 0) {
  1784. holeIndex += data[i - 1].length;
  1785. result.holes.push(holeIndex);
  1786. }
  1787. }
  1788. return result;
  1789. };
  1790. var vs_s$2 = ['attribute vec4 a_Position;', 'void main() {', 'gl_Position = a_Position;', 'gl_PointSize = 30.0;', '}'].join('');
  1791. var fs_s$2 = ['precision mediump float;', 'uniform vec4 u_FragColor;', 'void main() {', 'gl_FragColor = u_FragColor;', '}'].join('');
  1792. function draw$4(gl, data, options) {
  1793. // alert(draw$4)
  1794. if (!data) {
  1795. return;
  1796. }
  1797. // gl.clearColor(0.0, 0.0, 0.0, 1.0);
  1798. gl.clear(gl.COLOR_BUFFER_BIT);
  1799. gl.viewport(0, 0, gl.canvas.width, gl.canvas.height);
  1800. var program = initShaders(gl, vs_s$2, fs_s$2);
  1801. gl.enable(gl.BLEND);
  1802. gl.blendFunc(gl.SRC_ALPHA, gl.ONE);
  1803. var halfCanvasWidth = gl.canvas.width / 2;
  1804. var halfCanvasHeight = gl.canvas.height / 2;
  1805. // Bind the buffer object to target
  1806. gl.bindBuffer(gl.ARRAY_BUFFER, gl.createBuffer());
  1807. gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, gl.createBuffer());
  1808. var a_Position = gl.getAttribLocation(program, 'a_Position');
  1809. // Assign the buffer object to a_Position variable
  1810. gl.vertexAttribPointer(a_Position, 2, gl.FLOAT, false, 0, 0);
  1811. // Enable the assignment to a_Position variable
  1812. gl.enableVertexAttribArray(a_Position);
  1813. var uFragColor = gl.getUniformLocation(program, 'u_FragColor');
  1814. var colored = getColorData(options.fillStyle || 'red');
  1815. gl.uniform4f(uFragColor, colored[0] / 255, colored[1] / 255, colored[2] / 255, colored[3] / 255);
  1816. gl.lineWidth(options.lineWidth || 1);
  1817. var verticesArr = [];
  1818. var trianglesArr = [];
  1819. var maxSize = 65536;
  1820. var indexOffset = 0;
  1821. for (var i = 0, len = data.length; i < len; i++) {
  1822. var flatten = earcut.flatten(data[i].geometry._coordinates || data[i].geometry.coordinates);
  1823. var vertices = flatten.vertices;
  1824. indexOffset = verticesArr.length / 2;
  1825. for (var j = 0; j < vertices.length; j += 2) {
  1826. vertices[j] = (vertices[j] - halfCanvasWidth) / halfCanvasWidth;
  1827. vertices[j + 1] = (halfCanvasHeight - vertices[j + 1]) / halfCanvasHeight;
  1828. }
  1829. if ((verticesArr.length + vertices.length) / 2 > maxSize) {
  1830. gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(verticesArr), gl.STATIC_DRAW);
  1831. gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Uint16Array(trianglesArr), gl.STATIC_DRAW);
  1832. gl.drawElements(gl.TRIANGLES, trianglesArr.length, gl.UNSIGNED_SHORT, 0);
  1833. verticesArr.length = 0;
  1834. trianglesArr.length = 0;
  1835. indexOffset = 0;
  1836. }
  1837. for (var j = 0; j < vertices.length; j++) {
  1838. verticesArr.push(vertices[j]);
  1839. }
  1840. var triangles = earcut(vertices, flatten.holes, flatten.dimensions);
  1841. for (var j = 0; j < triangles.length; j++) {
  1842. trianglesArr.push(triangles[j] + indexOffset);
  1843. }
  1844. }
  1845. gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(verticesArr), gl.STATIC_DRAW);
  1846. gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Uint16Array(trianglesArr), gl.STATIC_DRAW);
  1847. gl.drawElements(gl.TRIANGLES, trianglesArr.length, gl.UNSIGNED_SHORT, 0);
  1848. gl.bindBuffer(gl.ARRAY_BUFFER, null);
  1849. gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, null);
  1850. }
  1851. var polygon = {
  1852. draw: draw$4
  1853. };
  1854. /**
  1855. * @author kyle / http://nikai.us/
  1856. */
  1857. var webglDrawSimple = {
  1858. draw: function draw(gl, dataSet, options) {
  1859. var data = dataSet instanceof DataSet ? dataSet.get() : dataSet;
  1860. // alert("webglDrawSimple");
  1861. if (data.length > 0) {
  1862. if (data[0].geometry.type == "LineString") {
  1863. line.draw(gl, data, options);
  1864. } else if (data[0].geometry.type == "Polygon" || data[0].geometry.type == "MultiPolygon") {
  1865. polygon.draw(gl, data, options);
  1866. } else {
  1867. point.draw(gl, data, options);
  1868. }
  1869. }
  1870. }
  1871. };
  1872. /**
  1873. * 根据弧线的坐标节点数组
  1874. */
  1875. function getCurvePoints(points, options) {
  1876. options = options || {};
  1877. var curvePoints = [];
  1878. for (var i = 0; i < points.length - 1; i++) {
  1879. var p = getCurveByTwoPoints(points[i], points[i + 1], options.count);
  1880. if (p && p.length > 0) {
  1881. curvePoints = curvePoints.concat(p);
  1882. }
  1883. }
  1884. return curvePoints;
  1885. }
  1886. /**
  1887. * 根据两点获取曲线坐标点数组
  1888. * @param Point 起点
  1889. * @param Point 终点
  1890. */
  1891. function getCurveByTwoPoints(obj1, obj2, count) {
  1892. if (!obj1 || !obj2) {
  1893. return null;
  1894. }
  1895. var B1 = function B1(x) {
  1896. return 1 - 2 * x + x * x;
  1897. };
  1898. var B2 = function B2(x) {
  1899. return 2 * x - 2 * x * x;
  1900. };
  1901. var B3 = function B3(x) {
  1902. return x * x;
  1903. };
  1904. var curveCoordinates = [];
  1905. var count = count || 40; // 曲线是由一些小的线段组成的,这个表示这个曲线所有到的折线的个数
  1906. var isFuture = false;
  1907. var t, h, h2, lat3, lng3, j, t2;
  1908. var LnArray = [];
  1909. var i = 0;
  1910. var inc = 0;
  1911. if (typeof obj2 == "undefined") {
  1912. if (typeof curveCoordinates != "undefined") {
  1913. curveCoordinates = [];
  1914. }
  1915. return;
  1916. }
  1917. var lat1 = parseFloat(obj1.lat);
  1918. var lat2 = parseFloat(obj2.lat);
  1919. var lng1 = parseFloat(obj1.lng);
  1920. var lng2 = parseFloat(obj2.lng);
  1921. // 计算曲线角度的方法
  1922. if (lng2 > lng1) {
  1923. if (parseFloat(lng2 - lng1) > 180) {
  1924. if (lng1 < 0) {
  1925. lng1 = parseFloat(180 + 180 + lng1);
  1926. lng2 = parseFloat(180 + 180 + lng2);
  1927. }
  1928. }
  1929. }
  1930. // 此时纠正了 lng1 lng2
  1931. j = 0;
  1932. t2 = 0;
  1933. // 纬度相同
  1934. if (lat2 == lat1) {
  1935. t = 0;
  1936. h = lng1 - lng2;
  1937. // 经度相同
  1938. } else if (lng2 == lng1) {
  1939. t = Math.PI / 2;
  1940. h = lat1 - lat2;
  1941. } else {
  1942. t = Math.atan((lat2 - lat1) / (lng2 - lng1));
  1943. h = (lat2 - lat1) / Math.sin(t);
  1944. }
  1945. if (t2 == 0) {
  1946. t2 = t + Math.PI / 5;
  1947. }
  1948. h2 = h / 2;
  1949. lng3 = h2 * Math.cos(t2) + lng1;
  1950. lat3 = h2 * Math.sin(t2) + lat1;
  1951. for (i = 0; i < count + 1; i++) {
  1952. var x = lng1 * B1(inc) + lng3 * B2(inc) + lng2 * B3(inc);
  1953. var y = lat1 * B1(inc) + lat3 * B2(inc) + lat2 * B3(inc);
  1954. var lng1_src = obj1.lng;
  1955. var lng2_src = obj2.lng;
  1956. curveCoordinates.push([lng1_src < 0 && lng2_src > 0 ? x - 360 : x, y]);
  1957. inc = inc + 1 / count;
  1958. }
  1959. return curveCoordinates;
  1960. }
  1961. var curve = {
  1962. getPoints: getCurvePoints
  1963. };
  1964. /*
  1965. FDEB algorithm implementation [www.win.tue.nl/~dholten/papers/forcebundles_eurovis.pdf].
  1966. Author: (github.com/upphiminn)
  1967. 2013
  1968. */
  1969. var ForceEdgeBundling = function ForceEdgeBundling() {
  1970. var data_nodes = {},
  1971. // {'nodeid':{'x':,'y':},..}
  1972. data_edges = [],
  1973. // [{'source':'nodeid1', 'target':'nodeid2'},..]
  1974. compatibility_list_for_edge = [],
  1975. subdivision_points_for_edge = [],
  1976. K = 0.1,
  1977. // global bundling constant controling edge stiffness
  1978. S_initial = 0.1,
  1979. // init. distance to move points
  1980. P_initial = 1,
  1981. // init. subdivision number
  1982. P_rate = 2,
  1983. // subdivision rate increase
  1984. C = 6,
  1985. // number of cycles to perform
  1986. I_initial = 70,
  1987. // init. number of iterations for cycle
  1988. I_rate = 0.6666667,
  1989. // rate at which iteration number decreases i.e. 2/3
  1990. compatibility_threshold = 0.6,
  1991. invers_quadratic_mode = false,
  1992. eps = 1e-8;
  1993. /*** Geometry Helper Methods ***/
  1994. function vector_dot_product(p, q) {
  1995. return p.x * q.x + p.y * q.y;
  1996. }
  1997. function edge_as_vector(P) {
  1998. return { 'x': data_nodes[P.target].x - data_nodes[P.source].x,
  1999. 'y': data_nodes[P.target].y - data_nodes[P.source].y };
  2000. }
  2001. function edge_length(e) {
  2002. return Math.sqrt(Math.pow(data_nodes[e.source].x - data_nodes[e.target].x, 2) + Math.pow(data_nodes[e.source].y - data_nodes[e.target].y, 2));
  2003. }
  2004. function custom_edge_length(e) {
  2005. return Math.sqrt(Math.pow(e.source.x - e.target.x, 2) + Math.pow(e.source.y - e.target.y, 2));
  2006. }
  2007. function edge_midpoint(e) {
  2008. var middle_x = (data_nodes[e.source].x + data_nodes[e.target].x) / 2.0;
  2009. var middle_y = (data_nodes[e.source].y + data_nodes[e.target].y) / 2.0;
  2010. return { 'x': middle_x, 'y': middle_y };
  2011. }
  2012. function compute_divided_edge_length(e_idx) {
  2013. var length = 0;
  2014. for (var i = 1; i < subdivision_points_for_edge[e_idx].length; i++) {
  2015. var segment_length = euclidean_distance(subdivision_points_for_edge[e_idx][i], subdivision_points_for_edge[e_idx][i - 1]);
  2016. length += segment_length;
  2017. }
  2018. return length;
  2019. }
  2020. function euclidean_distance(p, q) {
  2021. return Math.sqrt(Math.pow(p.x - q.x, 2) + Math.pow(p.y - q.y, 2));
  2022. }
  2023. function project_point_on_line(p, Q) {
  2024. var L = Math.sqrt((Q.target.x - Q.source.x) * (Q.target.x - Q.source.x) + (Q.target.y - Q.source.y) * (Q.target.y - Q.source.y));
  2025. var r = ((Q.source.y - p.y) * (Q.source.y - Q.target.y) - (Q.source.x - p.x) * (Q.target.x - Q.source.x)) / (L * L);
  2026. return { 'x': Q.source.x + r * (Q.target.x - Q.source.x), 'y': Q.source.y + r * (Q.target.y - Q.source.y) };
  2027. }
  2028. /*** ********************** ***/
  2029. /*** Initialization Methods ***/
  2030. function initialize_edge_subdivisions() {
  2031. for (var i = 0; i < data_edges.length; i++) {
  2032. if (P_initial == 1) subdivision_points_for_edge[i] = []; //0 subdivisions
  2033. else {
  2034. subdivision_points_for_edge[i] = [];
  2035. subdivision_points_for_edge[i].push(data_nodes[data_edges[i].source]);
  2036. subdivision_points_for_edge[i].push(data_nodes[data_edges[i].target]);
  2037. }
  2038. }
  2039. }
  2040. function initialize_compatibility_lists() {
  2041. for (var i = 0; i < data_edges.length; i++) {
  2042. compatibility_list_for_edge[i] = [];
  2043. } //0 compatible edges.
  2044. }
  2045. function filter_self_loops(edgelist) {
  2046. var filtered_edge_list = [];
  2047. for (var e = 0; e < edgelist.length; e++) {
  2048. if (data_nodes[edgelist[e].source].x != data_nodes[edgelist[e].target].x && data_nodes[edgelist[e].source].y != data_nodes[edgelist[e].target].y) {
  2049. //or smaller than eps
  2050. filtered_edge_list.push(edgelist[e]);
  2051. }
  2052. }
  2053. return filtered_edge_list;
  2054. }
  2055. /*** ********************** ***/
  2056. /*** Force Calculation Methods ***/
  2057. function apply_spring_force(e_idx, i, kP) {
  2058. var prev = subdivision_points_for_edge[e_idx][i - 1];
  2059. var next = subdivision_points_for_edge[e_idx][i + 1];
  2060. var crnt = subdivision_points_for_edge[e_idx][i];
  2061. var x = prev.x - crnt.x + next.x - crnt.x;
  2062. var y = prev.y - crnt.y + next.y - crnt.y;
  2063. x *= kP;
  2064. y *= kP;
  2065. return { 'x': x, 'y': y };
  2066. }
  2067. function apply_electrostatic_force(e_idx, i, S) {
  2068. var sum_of_forces = { 'x': 0, 'y': 0 };
  2069. var compatible_edges_list = compatibility_list_for_edge[e_idx];
  2070. for (var oe = 0; oe < compatible_edges_list.length; oe++) {
  2071. var force = { 'x': subdivision_points_for_edge[compatible_edges_list[oe]][i].x - subdivision_points_for_edge[e_idx][i].x,
  2072. 'y': subdivision_points_for_edge[compatible_edges_list[oe]][i].y - subdivision_points_for_edge[e_idx][i].y };
  2073. if (Math.abs(force.x) > eps || Math.abs(force.y) > eps) {
  2074. var diff = 1 / Math.pow(custom_edge_length({ 'source': subdivision_points_for_edge[compatible_edges_list[oe]][i],
  2075. 'target': subdivision_points_for_edge[e_idx][i] }), 1);
  2076. sum_of_forces.x += force.x * diff;
  2077. sum_of_forces.y += force.y * diff;
  2078. }
  2079. }
  2080. return sum_of_forces;
  2081. }
  2082. function apply_resulting_forces_on_subdivision_points(e_idx, P, S) {
  2083. var kP = K / (edge_length(data_edges[e_idx]) * (P + 1)); // kP=K/|P|(number of segments), where |P| is the initial length of edge P.
  2084. // (length * (num of sub division pts - 1))
  2085. var resulting_forces_for_subdivision_points = [{ 'x': 0, 'y': 0 }];
  2086. for (var i = 1; i < P + 1; i++) {
  2087. // exclude initial end points of the edge 0 and P+1
  2088. var resulting_force = { 'x': 0, 'y': 0 };
  2089. var spring_force = apply_spring_force(e_idx, i, kP);
  2090. var electrostatic_force = apply_electrostatic_force(e_idx, i, S);
  2091. resulting_force.x = S * (spring_force.x + electrostatic_force.x);
  2092. resulting_force.y = S * (spring_force.y + electrostatic_force.y);
  2093. resulting_forces_for_subdivision_points.push(resulting_force);
  2094. }
  2095. resulting_forces_for_subdivision_points.push({ 'x': 0, 'y': 0 });
  2096. return resulting_forces_for_subdivision_points;
  2097. }
  2098. /*** ********************** ***/
  2099. /*** Edge Division Calculation Methods ***/
  2100. function update_edge_divisions(P) {
  2101. for (var e_idx = 0; e_idx < data_edges.length; e_idx++) {
  2102. if (P == 1) {
  2103. subdivision_points_for_edge[e_idx].push(data_nodes[data_edges[e_idx].source]); // source
  2104. subdivision_points_for_edge[e_idx].push(edge_midpoint(data_edges[e_idx])); // mid point
  2105. subdivision_points_for_edge[e_idx].push(data_nodes[data_edges[e_idx].target]); // target
  2106. } else {
  2107. var divided_edge_length = compute_divided_edge_length(e_idx);
  2108. var segment_length = divided_edge_length / (P + 1);
  2109. var current_segment_length = segment_length;
  2110. var new_subdivision_points = [];
  2111. new_subdivision_points.push(data_nodes[data_edges[e_idx].source]); //source
  2112. for (var i = 1; i < subdivision_points_for_edge[e_idx].length; i++) {
  2113. var old_segment_length = euclidean_distance(subdivision_points_for_edge[e_idx][i], subdivision_points_for_edge[e_idx][i - 1]);
  2114. while (old_segment_length > current_segment_length) {
  2115. var percent_position = current_segment_length / old_segment_length;
  2116. var new_subdivision_point_x = subdivision_points_for_edge[e_idx][i - 1].x;
  2117. var new_subdivision_point_y = subdivision_points_for_edge[e_idx][i - 1].y;
  2118. new_subdivision_point_x += percent_position * (subdivision_points_for_edge[e_idx][i].x - subdivision_points_for_edge[e_idx][i - 1].x);
  2119. new_subdivision_point_y += percent_position * (subdivision_points_for_edge[e_idx][i].y - subdivision_points_for_edge[e_idx][i - 1].y);
  2120. new_subdivision_points.push({ 'x': new_subdivision_point_x,
  2121. 'y': new_subdivision_point_y });
  2122. old_segment_length -= current_segment_length;
  2123. current_segment_length = segment_length;
  2124. }
  2125. current_segment_length -= old_segment_length;
  2126. }
  2127. new_subdivision_points.push(data_nodes[data_edges[e_idx].target]); //target
  2128. subdivision_points_for_edge[e_idx] = new_subdivision_points;
  2129. }
  2130. }
  2131. }
  2132. /*** ********************** ***/
  2133. /*** Edge compatibility measures ***/
  2134. function angle_compatibility(P, Q) {
  2135. var result = Math.abs(vector_dot_product(edge_as_vector(P), edge_as_vector(Q)) / (edge_length(P) * edge_length(Q)));
  2136. return result;
  2137. }
  2138. function scale_compatibility(P, Q) {
  2139. var lavg = (edge_length(P) + edge_length(Q)) / 2.0;
  2140. var result = 2.0 / (lavg / Math.min(edge_length(P), edge_length(Q)) + Math.max(edge_length(P), edge_length(Q)) / lavg);
  2141. return result;
  2142. }
  2143. function position_compatibility(P, Q) {
  2144. var lavg = (edge_length(P) + edge_length(Q)) / 2.0;
  2145. var midP = { 'x': (data_nodes[P.source].x + data_nodes[P.target].x) / 2.0,
  2146. 'y': (data_nodes[P.source].y + data_nodes[P.target].y) / 2.0 };
  2147. var midQ = { 'x': (data_nodes[Q.source].x + data_nodes[Q.target].x) / 2.0,
  2148. 'y': (data_nodes[Q.source].y + data_nodes[Q.target].y) / 2.0 };
  2149. var result = lavg / (lavg + euclidean_distance(midP, midQ));
  2150. return result;
  2151. }
  2152. function edge_visibility(P, Q) {
  2153. var I0 = project_point_on_line(data_nodes[Q.source], { 'source': data_nodes[P.source],
  2154. 'target': data_nodes[P.target] });
  2155. var I1 = project_point_on_line(data_nodes[Q.target], { 'source': data_nodes[P.source],
  2156. 'target': data_nodes[P.target] }); //send acutal edge points positions
  2157. var midI = { 'x': (I0.x + I1.x) / 2.0,
  2158. 'y': (I0.y + I1.y) / 2.0 };
  2159. var midP = { 'x': (data_nodes[P.source].x + data_nodes[P.target].x) / 2.0,
  2160. 'y': (data_nodes[P.source].y + data_nodes[P.target].y) / 2.0 };
  2161. var result = Math.max(0, 1 - 2 * euclidean_distance(midP, midI) / euclidean_distance(I0, I1));
  2162. return result;
  2163. }
  2164. function visibility_compatibility(P, Q) {
  2165. return Math.min(edge_visibility(P, Q), edge_visibility(Q, P));
  2166. }
  2167. function compatibility_score(P, Q) {
  2168. var result = angle_compatibility(P, Q) * scale_compatibility(P, Q) * position_compatibility(P, Q) * visibility_compatibility(P, Q);
  2169. return result;
  2170. }
  2171. function are_compatible(P, Q) {
  2172. // console.log('compatibility ' + P.source +' - '+ P.target + ' and ' + Q.source +' '+ Q.target);
  2173. return compatibility_score(P, Q) >= compatibility_threshold;
  2174. }
  2175. function compute_compatibility_lists() {
  2176. for (var e = 0; e < data_edges.length - 1; e++) {
  2177. for (var oe = e + 1; oe < data_edges.length; oe++) {
  2178. // don't want any duplicates
  2179. if (e == oe) continue;else {
  2180. if (are_compatible(data_edges[e], data_edges[oe])) {
  2181. compatibility_list_for_edge[e].push(oe);
  2182. compatibility_list_for_edge[oe].push(e);
  2183. }
  2184. }
  2185. }
  2186. }
  2187. }
  2188. /*** ************************ ***/
  2189. /*** Main Bundling Loop Methods ***/
  2190. var forcebundle = function forcebundle() {
  2191. var S = S_initial;
  2192. var I = I_initial;
  2193. var P = P_initial;
  2194. initialize_edge_subdivisions();
  2195. initialize_compatibility_lists();
  2196. update_edge_divisions(P);
  2197. compute_compatibility_lists();
  2198. for (var cycle = 0; cycle < C; cycle++) {
  2199. for (var iteration = 0; iteration < I; iteration++) {
  2200. var forces = [];
  2201. for (var edge = 0; edge < data_edges.length; edge++) {
  2202. forces[edge] = apply_resulting_forces_on_subdivision_points(edge, P, S);
  2203. }
  2204. for (var e = 0; e < data_edges.length; e++) {
  2205. for (var i = 0; i < P + 1; i++) {
  2206. subdivision_points_for_edge[e][i].x += forces[e][i].x;
  2207. subdivision_points_for_edge[e][i].y += forces[e][i].y;
  2208. }
  2209. }
  2210. }
  2211. //prepare for next cycle
  2212. S = S / 2;
  2213. P = P * 2;
  2214. I = I_rate * I;
  2215. update_edge_divisions(P);
  2216. // console.log('C' + cycle);
  2217. // console.log('P' + P);
  2218. // console.log('S' + S);
  2219. }
  2220. return subdivision_points_for_edge;
  2221. };
  2222. /*** ************************ ***/
  2223. /*** Getters/Setters Methods ***/
  2224. forcebundle.nodes = function (nl) {
  2225. if (arguments.length == 0) {
  2226. return data_nodes;
  2227. } else {
  2228. data_nodes = nl;
  2229. }
  2230. return forcebundle;
  2231. };
  2232. forcebundle.edges = function (ll) {
  2233. if (arguments.length == 0) {
  2234. return data_edges;
  2235. } else {
  2236. data_edges = filter_self_loops(ll); //remove edges to from to the same point
  2237. }
  2238. return forcebundle;
  2239. };
  2240. forcebundle.bundling_stiffness = function (k) {
  2241. if (arguments.length == 0) {
  2242. return K;
  2243. } else {
  2244. K = k;
  2245. }
  2246. return forcebundle;
  2247. };
  2248. forcebundle.step_size = function (step) {
  2249. if (arguments.length == 0) {
  2250. return S_initial;
  2251. } else {
  2252. S_initial = step;
  2253. }
  2254. return forcebundle;
  2255. };
  2256. forcebundle.cycles = function (c) {
  2257. if (arguments.length == 0) {
  2258. return C;
  2259. } else {
  2260. C = c;
  2261. }
  2262. return forcebundle;
  2263. };
  2264. forcebundle.iterations = function (i) {
  2265. if (arguments.length == 0) {
  2266. return I_initial;
  2267. } else {
  2268. I_initial = i;
  2269. }
  2270. return forcebundle;
  2271. };
  2272. forcebundle.iterations_rate = function (i) {
  2273. if (arguments.length == 0) {
  2274. return I_rate;
  2275. } else {
  2276. I_rate = i;
  2277. }
  2278. return forcebundle;
  2279. };
  2280. forcebundle.subdivision_points_seed = function (p) {
  2281. if (arguments.length == 0) {
  2282. return P;
  2283. } else {
  2284. P = p;
  2285. }
  2286. return forcebundle;
  2287. };
  2288. forcebundle.subdivision_rate = function (r) {
  2289. if (arguments.length == 0) {
  2290. return P_rate;
  2291. } else {
  2292. P_rate = r;
  2293. }
  2294. return forcebundle;
  2295. };
  2296. forcebundle.compatbility_threshold = function (t) {
  2297. if (arguments.length == 0) {
  2298. return compatbility_threshold;
  2299. } else {
  2300. compatibility_threshold = t;
  2301. }
  2302. return forcebundle;
  2303. };
  2304. /*** ************************ ***/
  2305. return forcebundle;
  2306. };
  2307. /**
  2308. * @author kyle / http://nikai.us/
  2309. */
  2310. /**
  2311. * Category
  2312. * @param {Object} splitList:
  2313. * {
  2314. * other: 1,
  2315. * 1: 2,
  2316. * 2: 3,
  2317. * 3: 4,
  2318. * 4: 5,
  2319. * 5: 6,
  2320. * 6: 7
  2321. * }
  2322. */
  2323. function Category(splitList) {
  2324. this.splitList = splitList || {
  2325. other: 1
  2326. };
  2327. }
  2328. Category.prototype.get = function (count) {
  2329. var splitList = this.splitList;
  2330. var value = splitList['other'];
  2331. for (var i in splitList) {
  2332. if (count == i) {
  2333. value = splitList[i];
  2334. break;
  2335. }
  2336. }
  2337. return value;
  2338. };
  2339. /**
  2340. * 根据DataSet自动生成对应的splitList
  2341. */
  2342. Category.prototype.generateByDataSet = function (dataSet, color) {
  2343. var colors = color || ['rgba(255, 255, 0, 0.8)', 'rgba(253, 98, 104, 0.8)', 'rgba(255, 146, 149, 0.8)', 'rgba(255, 241, 193, 0.8)', 'rgba(110, 176, 253, 0.8)', 'rgba(52, 139, 251, 0.8)', 'rgba(17, 102, 252, 0.8)'];
  2344. var data = dataSet.get();
  2345. this.splitList = {};
  2346. var count = 0;
  2347. for (var i = 0; i < data.length; i++) {
  2348. if (this.splitList[data[i].count] === undefined) {
  2349. this.splitList[data[i].count] = colors[count];
  2350. count++;
  2351. }
  2352. if (count >= colors.length - 1) {
  2353. break;
  2354. }
  2355. }
  2356. this.splitList['other'] = colors[colors.length - 1];
  2357. };
  2358. Category.prototype.getLegend = function (options) {
  2359. var splitList = this.splitList;
  2360. var container = document.createElement('div');
  2361. container.style.cssText = "background:#fff; padding: 5px; border: 1px solid #ccc;";
  2362. var html = '';
  2363. for (var key in splitList) {
  2364. html += '<div style="line-height: 19px;" value="' + key + '"><span style="vertical-align: -2px; display: inline-block; width: 30px;height: 19px;background:' + splitList[key] + ';"></span><span style="margin-left: 3px;">' + key + '<span></div>';
  2365. }
  2366. container.innerHTML = html;
  2367. return container;
  2368. };
  2369. /**
  2370. * @author kyle / http://nikai.us/
  2371. */
  2372. /**
  2373. * Choropleth
  2374. * @param {Object} splitList:
  2375. * [
  2376. * {
  2377. * start: 0,
  2378. * end: 2,
  2379. * value: randomColor()
  2380. * },{
  2381. * start: 2,
  2382. * end: 4,
  2383. * value: randomColor()
  2384. * },{
  2385. * start: 4,
  2386. * value: randomColor()
  2387. * }
  2388. * ];
  2389. *
  2390. */
  2391. function Choropleth(splitList) {
  2392. this.splitList = splitList || [{
  2393. start: 0,
  2394. value: 'red'
  2395. }];
  2396. }
  2397. Choropleth.prototype.get = function (count) {
  2398. var splitList = this.splitList;
  2399. var value = false;
  2400. for (var i = 0; i < splitList.length; i++) {
  2401. if ((splitList[i].start === undefined || splitList[i].start !== undefined && count >= splitList[i].start) && (splitList[i].end === undefined || splitList[i].end !== undefined && count < splitList[i].end)) {
  2402. value = splitList[i].value;
  2403. break;
  2404. }
  2405. }
  2406. return value;
  2407. };
  2408. /**
  2409. * 根据DataSet自动生成对应的splitList
  2410. */
  2411. Choropleth.prototype.generateByDataSet = function (dataSet) {
  2412. var min = dataSet.getMin('count');
  2413. var max = dataSet.getMax('count');
  2414. this.generateByMinMax(min, max);
  2415. };
  2416. /**
  2417. * 根据DataSet自动生成对应的splitList
  2418. */
  2419. Choropleth.prototype.generateByMinMax = function (min, max) {
  2420. var colors = ['rgba(255, 255, 0, 0.8)', 'rgba(253, 98, 104, 0.8)', 'rgba(255, 146, 149, 0.8)', 'rgba(255, 241, 193, 0.8)', 'rgba(110, 176, 253, 0.8)', 'rgba(52, 139, 251, 0.8)', 'rgba(17, 102, 252, 0.8)'];
  2421. var splitNum = Number((max - min) / 7);
  2422. // console.log(splitNum)
  2423. max = Number(max);
  2424. var index = Number(min);
  2425. this.splitList = [];
  2426. var count = 0;
  2427. while (index < max) {
  2428. this.splitList.push({
  2429. start: index,
  2430. end: index + splitNum,
  2431. value: colors[count]
  2432. });
  2433. count++;
  2434. index += splitNum;
  2435. // console.log(index, max)
  2436. }
  2437. // console.log('splitNum')
  2438. };
  2439. Choropleth.prototype.getLegend = function (options) {
  2440. var splitList = this.splitList;
  2441. };
  2442. /**
  2443. * @author Mofei<http://www.zhuwenlong.com>
  2444. */
  2445. var MapHelper = function () {
  2446. function MapHelper(id, type, opt) {
  2447. classCallCheck(this, MapHelper);
  2448. if (!id || !type) {
  2449. console.warn('id 和 type 为必填项');
  2450. return false;
  2451. }
  2452. if (type == 'baidu') {
  2453. if (!BMap) {
  2454. console.warn('请先引入百度地图JS API');
  2455. return false;
  2456. }
  2457. } else {
  2458. console.warn('暂不支持你的地图类型');
  2459. }
  2460. this.type = type;
  2461. var center = opt && opt.center ? opt.center : [106.962497, 38.208726];
  2462. var zoom = opt && opt.zoom ? opt.zoom : 5;
  2463. var map = this.map = new BMap.Map(id, {
  2464. enableMapClick: false
  2465. });
  2466. map.centerAndZoom(new BMap.Point(center[0], center[1]), zoom);
  2467. map.enableScrollWheelZoom(true);
  2468. map.setMapStyle({
  2469. style: 'light'
  2470. });
  2471. }
  2472. createClass(MapHelper, [{
  2473. key: 'addLayer',
  2474. value: function addLayer(datas, options) {
  2475. if (this.type == 'baidu') {
  2476. return new mapv.baiduMapLayer(this.map, dataSet, options);
  2477. }
  2478. }
  2479. }, {
  2480. key: 'getMap',
  2481. value: function getMap() {
  2482. return this.map;
  2483. }
  2484. }]);
  2485. return MapHelper;
  2486. }();
  2487. /**
  2488. * 一直覆盖在当前地图视野的Canvas对象
  2489. *
  2490. * @author nikai (@胖嘟嘟的骨头, nikai@baidu.com)
  2491. *
  2492. * @param
  2493. * {
  2494. * map 地图实例对象
  2495. * }
  2496. */
  2497. function CanvasLayer(options) {
  2498. this.options = options || {};
  2499. this.paneName = this.options.paneName || 'mapPane';
  2500. this.context = this.options.context || '2d';
  2501. this.zIndex = this.options.zIndex || 0;
  2502. this.mixBlendMode = this.options.mixBlendMode || null;
  2503. this.enableMassClear = this.options.enableMassClear;
  2504. this._map = options.map;
  2505. this._lastDrawTime = null;
  2506. this.show();
  2507. }
  2508. var global$3 = typeof window === 'undefined' ? {} : window;
  2509. var BMap$1 = global$3.BMap || global$3.BMapGL;
  2510. if (BMap$1) {
  2511. CanvasLayer.prototype = new BMap$1.Overlay();
  2512. CanvasLayer.prototype.initialize = function (map) {
  2513. this._map = map;
  2514. var canvas = this.canvas = document.createElement("canvas");
  2515. canvas.style.cssText = "position:absolute;" + "left:0;" + "top:0;" + "z-index:" + this.zIndex + ";user-select:none;";
  2516. canvas.style.mixBlendMode = this.mixBlendMode;
  2517. this.adjustSize();
  2518. var pane = map.getPanes()[this.paneName];
  2519. if (!pane) {
  2520. pane = map.getPanes().floatShadow;
  2521. }
  2522. pane.appendChild(canvas);
  2523. var that = this;
  2524. map.addEventListener('resize', function () {
  2525. that.adjustSize();
  2526. that._draw();
  2527. });
  2528. map.addEventListener('update', function () {
  2529. that._draw();
  2530. });
  2531. /*
  2532. map.addEventListener('moving', function() {
  2533. that._draw();
  2534. });
  2535. */
  2536. if (this.options.updateImmediate) {
  2537. setTimeout(function () {
  2538. that._draw();
  2539. }, 100);
  2540. }
  2541. return this.canvas;
  2542. };
  2543. CanvasLayer.prototype.adjustSize = function () {
  2544. var size = this._map.getSize();
  2545. var canvas = this.canvas;
  2546. var devicePixelRatio = this.devicePixelRatio = global$3.devicePixelRatio || 1;
  2547. canvas.width = size.width * devicePixelRatio;
  2548. canvas.height = size.height * devicePixelRatio;
  2549. if (this.context == '2d') {
  2550. canvas.getContext(this.context).scale(devicePixelRatio, devicePixelRatio);
  2551. }
  2552. canvas.style.width = size.width + "px";
  2553. canvas.style.height = size.height + "px";
  2554. };
  2555. CanvasLayer.prototype.draw = function () {
  2556. // alert("CanvasLayer.prototype.draw");
  2557. var self = this;
  2558. if (this.options.updateImmediate) {
  2559. self._draw();
  2560. } else {
  2561. clearTimeout(self.timeoutID);
  2562. self.timeoutID = setTimeout(function () {
  2563. self._draw();
  2564. }, 15);
  2565. }
  2566. };
  2567. CanvasLayer.prototype._draw = function () {
  2568. // alert("CanvasLayer.prototype.draw_");
  2569. var map = this._map;
  2570. var size = map.getSize();
  2571. var center = map.getCenter();
  2572. if (center) {
  2573. var pixel = map.pointToOverlayPixel(center);
  2574. this.canvas.style.left = pixel.x - size.width / 2 + 'px';
  2575. this.canvas.style.top = pixel.y - size.height / 2 + 'px';
  2576. this.dispatchEvent('draw');
  2577. this.options.update && this.options.update.call(this);
  2578. }
  2579. };
  2580. CanvasLayer.prototype.getContainer = function () {
  2581. return this.canvas;
  2582. };
  2583. CanvasLayer.prototype.show = function () {
  2584. if (!this.canvas) {
  2585. this._map.addOverlay(this);
  2586. }
  2587. this.canvas.style.display = "block";
  2588. };
  2589. CanvasLayer.prototype.hide = function () {
  2590. this.canvas.style.display = "none";
  2591. //this._map.removeOverlay(this);
  2592. };
  2593. CanvasLayer.prototype.setZIndex = function (zIndex) {
  2594. this.zIndex = zIndex;
  2595. this.canvas.style.zIndex = this.zIndex;
  2596. };
  2597. CanvasLayer.prototype.getZIndex = function () {
  2598. return this.zIndex;
  2599. };
  2600. }
  2601. /**
  2602. * Tween.js - Licensed under the MIT license
  2603. * https://github.com/tweenjs/tween.js
  2604. * ----------------------------------------------
  2605. *
  2606. * See https://github.com/tweenjs/tween.js/graphs/contributors for the full list of contributors.
  2607. * Thank you all, you're awesome!
  2608. */
  2609. var TWEEN = TWEEN || function () {
  2610. var _tweens = [];
  2611. return {
  2612. getAll: function getAll() {
  2613. return _tweens;
  2614. },
  2615. removeAll: function removeAll() {
  2616. _tweens = [];
  2617. },
  2618. add: function add(tween) {
  2619. _tweens.push(tween);
  2620. },
  2621. remove: function remove(tween) {
  2622. var i = _tweens.indexOf(tween);
  2623. if (i !== -1) {
  2624. _tweens.splice(i, 1);
  2625. }
  2626. },
  2627. update: function update(time, preserve) {
  2628. if (_tweens.length === 0) {
  2629. return false;
  2630. }
  2631. var i = 0;
  2632. time = time !== undefined ? time : TWEEN.now();
  2633. while (i < _tweens.length) {
  2634. if (_tweens[i].update(time) || preserve) {
  2635. i++;
  2636. } else {
  2637. _tweens.splice(i, 1);
  2638. }
  2639. }
  2640. return true;
  2641. }
  2642. };
  2643. }();
  2644. // Include a performance.now polyfill.
  2645. // In node.js, use process.hrtime.
  2646. if (typeof window === 'undefined' && typeof process !== 'undefined') {
  2647. TWEEN.now = function () {
  2648. var time = process.hrtime();
  2649. // Convert [seconds, nanoseconds] to milliseconds.
  2650. return time[0] * 1000 + time[1] / 1000000;
  2651. };
  2652. }
  2653. // In a browser, use window.performance.now if it is available.
  2654. else if (typeof window !== 'undefined' && window.performance !== undefined && window.performance.now !== undefined) {
  2655. // This must be bound, because directly assigning this function
  2656. // leads to an invocation exception in Chrome.
  2657. TWEEN.now = window.performance.now.bind(window.performance);
  2658. }
  2659. // Use Date.now if it is available.
  2660. else if (Date.now !== undefined) {
  2661. TWEEN.now = Date.now;
  2662. }
  2663. // Otherwise, use 'new Date().getTime()'.
  2664. else {
  2665. TWEEN.now = function () {
  2666. return new Date().getTime();
  2667. };
  2668. }
  2669. TWEEN.Tween = function (object) {
  2670. var _object = object;
  2671. var _valuesStart = {};
  2672. var _valuesEnd = {};
  2673. var _valuesStartRepeat = {};
  2674. var _duration = 1000;
  2675. var _repeat = 0;
  2676. var _repeatDelayTime;
  2677. var _yoyo = false;
  2678. var _isPlaying = false;
  2679. var _reversed = false;
  2680. var _delayTime = 0;
  2681. var _startTime = null;
  2682. var _easingFunction = TWEEN.Easing.Linear.None;
  2683. var _interpolationFunction = TWEEN.Interpolation.Linear;
  2684. var _chainedTweens = [];
  2685. var _onStartCallback = null;
  2686. var _onStartCallbackFired = false;
  2687. var _onUpdateCallback = null;
  2688. var _onCompleteCallback = null;
  2689. var _onStopCallback = null;
  2690. this.to = function (properties, duration) {
  2691. _valuesEnd = properties;
  2692. if (duration !== undefined) {
  2693. _duration = duration;
  2694. }
  2695. return this;
  2696. };
  2697. this.start = function (time) {
  2698. TWEEN.add(this);
  2699. _isPlaying = true;
  2700. _onStartCallbackFired = false;
  2701. _startTime = time !== undefined ? time : TWEEN.now();
  2702. _startTime += _delayTime;
  2703. for (var property in _valuesEnd) {
  2704. // Check if an Array was provided as property value
  2705. if (_valuesEnd[property] instanceof Array) {
  2706. if (_valuesEnd[property].length === 0) {
  2707. continue;
  2708. }
  2709. // Create a local copy of the Array with the start value at the front
  2710. _valuesEnd[property] = [_object[property]].concat(_valuesEnd[property]);
  2711. }
  2712. // If `to()` specifies a property that doesn't exist in the source object,
  2713. // we should not set that property in the object
  2714. if (_object[property] === undefined) {
  2715. continue;
  2716. }
  2717. // Save the starting value.
  2718. _valuesStart[property] = _object[property];
  2719. if (_valuesStart[property] instanceof Array === false) {
  2720. _valuesStart[property] *= 1.0; // Ensures we're using numbers, not strings
  2721. }
  2722. _valuesStartRepeat[property] = _valuesStart[property] || 0;
  2723. }
  2724. return this;
  2725. };
  2726. this.stop = function () {
  2727. if (!_isPlaying) {
  2728. return this;
  2729. }
  2730. TWEEN.remove(this);
  2731. _isPlaying = false;
  2732. if (_onStopCallback !== null) {
  2733. _onStopCallback.call(_object, _object);
  2734. }
  2735. this.stopChainedTweens();
  2736. return this;
  2737. };
  2738. this.end = function () {
  2739. this.update(_startTime + _duration);
  2740. return this;
  2741. };
  2742. this.stopChainedTweens = function () {
  2743. for (var i = 0, numChainedTweens = _chainedTweens.length; i < numChainedTweens; i++) {
  2744. _chainedTweens[i].stop();
  2745. }
  2746. };
  2747. this.delay = function (amount) {
  2748. _delayTime = amount;
  2749. return this;
  2750. };
  2751. this.repeat = function (times) {
  2752. _repeat = times;
  2753. return this;
  2754. };
  2755. this.repeatDelay = function (amount) {
  2756. _repeatDelayTime = amount;
  2757. return this;
  2758. };
  2759. this.yoyo = function (yoyo) {
  2760. _yoyo = yoyo;
  2761. return this;
  2762. };
  2763. this.easing = function (easing) {
  2764. _easingFunction = easing;
  2765. return this;
  2766. };
  2767. this.interpolation = function (interpolation) {
  2768. _interpolationFunction = interpolation;
  2769. return this;
  2770. };
  2771. this.chain = function () {
  2772. _chainedTweens = arguments;
  2773. return this;
  2774. };
  2775. this.onStart = function (callback) {
  2776. _onStartCallback = callback;
  2777. return this;
  2778. };
  2779. this.onUpdate = function (callback) {
  2780. _onUpdateCallback = callback;
  2781. return this;
  2782. };
  2783. this.onComplete = function (callback) {
  2784. _onCompleteCallback = callback;
  2785. return this;
  2786. };
  2787. this.onStop = function (callback) {
  2788. _onStopCallback = callback;
  2789. return this;
  2790. };
  2791. this.update = function (time) {
  2792. var property;
  2793. var elapsed;
  2794. var value;
  2795. if (time < _startTime) {
  2796. return true;
  2797. }
  2798. if (_onStartCallbackFired === false) {
  2799. if (_onStartCallback !== null) {
  2800. _onStartCallback.call(_object, _object);
  2801. }
  2802. _onStartCallbackFired = true;
  2803. }
  2804. elapsed = (time - _startTime) / _duration;
  2805. elapsed = elapsed > 1 ? 1 : elapsed;
  2806. value = _easingFunction(elapsed);
  2807. for (property in _valuesEnd) {
  2808. // Don't update properties that do not exist in the source object
  2809. if (_valuesStart[property] === undefined) {
  2810. continue;
  2811. }
  2812. var start = _valuesStart[property] || 0;
  2813. var end = _valuesEnd[property];
  2814. if (end instanceof Array) {
  2815. _object[property] = _interpolationFunction(end, value);
  2816. } else {
  2817. // Parses relative end values with start as base (e.g.: +10, -3)
  2818. if (typeof end === 'string') {
  2819. if (end.charAt(0) === '+' || end.charAt(0) === '-') {
  2820. end = start + parseFloat(end);
  2821. } else {
  2822. end = parseFloat(end);
  2823. }
  2824. }
  2825. // Protect against non numeric properties.
  2826. if (typeof end === 'number') {
  2827. _object[property] = start + (end - start) * value;
  2828. }
  2829. }
  2830. }
  2831. if (_onUpdateCallback !== null) {
  2832. _onUpdateCallback.call(_object, value);
  2833. }
  2834. if (elapsed === 1) {
  2835. if (_repeat > 0) {
  2836. if (isFinite(_repeat)) {
  2837. _repeat--;
  2838. }
  2839. // Reassign starting values, restart by making startTime = now
  2840. for (property in _valuesStartRepeat) {
  2841. if (typeof _valuesEnd[property] === 'string') {
  2842. _valuesStartRepeat[property] = _valuesStartRepeat[property] + parseFloat(_valuesEnd[property]);
  2843. }
  2844. if (_yoyo) {
  2845. var tmp = _valuesStartRepeat[property];
  2846. _valuesStartRepeat[property] = _valuesEnd[property];
  2847. _valuesEnd[property] = tmp;
  2848. }
  2849. _valuesStart[property] = _valuesStartRepeat[property];
  2850. }
  2851. if (_yoyo) {
  2852. _reversed = !_reversed;
  2853. }
  2854. if (_repeatDelayTime !== undefined) {
  2855. _startTime = time + _repeatDelayTime;
  2856. } else {
  2857. _startTime = time + _delayTime;
  2858. }
  2859. return true;
  2860. } else {
  2861. if (_onCompleteCallback !== null) {
  2862. _onCompleteCallback.call(_object, _object);
  2863. }
  2864. for (var i = 0, numChainedTweens = _chainedTweens.length; i < numChainedTweens; i++) {
  2865. // Make the chained tweens start exactly at the time they should,
  2866. // even if the `update()` method was called way past the duration of the tween
  2867. _chainedTweens[i].start(_startTime + _duration);
  2868. }
  2869. return false;
  2870. }
  2871. }
  2872. return true;
  2873. };
  2874. };
  2875. TWEEN.Easing = {
  2876. Linear: {
  2877. None: function None(k) {
  2878. return k;
  2879. }
  2880. },
  2881. Quadratic: {
  2882. In: function In(k) {
  2883. return k * k;
  2884. },
  2885. Out: function Out(k) {
  2886. return k * (2 - k);
  2887. },
  2888. InOut: function InOut(k) {
  2889. if ((k *= 2) < 1) {
  2890. return 0.5 * k * k;
  2891. }
  2892. return -0.5 * (--k * (k - 2) - 1);
  2893. }
  2894. },
  2895. Cubic: {
  2896. In: function In(k) {
  2897. return k * k * k;
  2898. },
  2899. Out: function Out(k) {
  2900. return --k * k * k + 1;
  2901. },
  2902. InOut: function InOut(k) {
  2903. if ((k *= 2) < 1) {
  2904. return 0.5 * k * k * k;
  2905. }
  2906. return 0.5 * ((k -= 2) * k * k + 2);
  2907. }
  2908. },
  2909. Quartic: {
  2910. In: function In(k) {
  2911. return k * k * k * k;
  2912. },
  2913. Out: function Out(k) {
  2914. return 1 - --k * k * k * k;
  2915. },
  2916. InOut: function InOut(k) {
  2917. if ((k *= 2) < 1) {
  2918. return 0.5 * k * k * k * k;
  2919. }
  2920. return -0.5 * ((k -= 2) * k * k * k - 2);
  2921. }
  2922. },
  2923. Quintic: {
  2924. In: function In(k) {
  2925. return k * k * k * k * k;
  2926. },
  2927. Out: function Out(k) {
  2928. return --k * k * k * k * k + 1;
  2929. },
  2930. InOut: function InOut(k) {
  2931. if ((k *= 2) < 1) {
  2932. return 0.5 * k * k * k * k * k;
  2933. }
  2934. return 0.5 * ((k -= 2) * k * k * k * k + 2);
  2935. }
  2936. },
  2937. Sinusoidal: {
  2938. In: function In(k) {
  2939. return 1 - Math.cos(k * Math.PI / 2);
  2940. },
  2941. Out: function Out(k) {
  2942. return Math.sin(k * Math.PI / 2);
  2943. },
  2944. InOut: function InOut(k) {
  2945. return 0.5 * (1 - Math.cos(Math.PI * k));
  2946. }
  2947. },
  2948. Exponential: {
  2949. In: function In(k) {
  2950. return k === 0 ? 0 : Math.pow(1024, k - 1);
  2951. },
  2952. Out: function Out(k) {
  2953. return k === 1 ? 1 : 1 - Math.pow(2, -10 * k);
  2954. },
  2955. InOut: function InOut(k) {
  2956. if (k === 0) {
  2957. return 0;
  2958. }
  2959. if (k === 1) {
  2960. return 1;
  2961. }
  2962. if ((k *= 2) < 1) {
  2963. return 0.5 * Math.pow(1024, k - 1);
  2964. }
  2965. return 0.5 * (-Math.pow(2, -10 * (k - 1)) + 2);
  2966. }
  2967. },
  2968. Circular: {
  2969. In: function In(k) {
  2970. return 1 - Math.sqrt(1 - k * k);
  2971. },
  2972. Out: function Out(k) {
  2973. return Math.sqrt(1 - --k * k);
  2974. },
  2975. InOut: function InOut(k) {
  2976. if ((k *= 2) < 1) {
  2977. return -0.5 * (Math.sqrt(1 - k * k) - 1);
  2978. }
  2979. return 0.5 * (Math.sqrt(1 - (k -= 2) * k) + 1);
  2980. }
  2981. },
  2982. Elastic: {
  2983. In: function In(k) {
  2984. if (k === 0) {
  2985. return 0;
  2986. }
  2987. if (k === 1) {
  2988. return 1;
  2989. }
  2990. return -Math.pow(2, 10 * (k - 1)) * Math.sin((k - 1.1) * 5 * Math.PI);
  2991. },
  2992. Out: function Out(k) {
  2993. if (k === 0) {
  2994. return 0;
  2995. }
  2996. if (k === 1) {
  2997. return 1;
  2998. }
  2999. return Math.pow(2, -10 * k) * Math.sin((k - 0.1) * 5 * Math.PI) + 1;
  3000. },
  3001. InOut: function InOut(k) {
  3002. if (k === 0) {
  3003. return 0;
  3004. }
  3005. if (k === 1) {
  3006. return 1;
  3007. }
  3008. k *= 2;
  3009. if (k < 1) {
  3010. return -0.5 * Math.pow(2, 10 * (k - 1)) * Math.sin((k - 1.1) * 5 * Math.PI);
  3011. }
  3012. return 0.5 * Math.pow(2, -10 * (k - 1)) * Math.sin((k - 1.1) * 5 * Math.PI) + 1;
  3013. }
  3014. },
  3015. Back: {
  3016. In: function In(k) {
  3017. var s = 1.70158;
  3018. return k * k * ((s + 1) * k - s);
  3019. },
  3020. Out: function Out(k) {
  3021. var s = 1.70158;
  3022. return --k * k * ((s + 1) * k + s) + 1;
  3023. },
  3024. InOut: function InOut(k) {
  3025. var s = 1.70158 * 1.525;
  3026. if ((k *= 2) < 1) {
  3027. return 0.5 * (k * k * ((s + 1) * k - s));
  3028. }
  3029. return 0.5 * ((k -= 2) * k * ((s + 1) * k + s) + 2);
  3030. }
  3031. },
  3032. Bounce: {
  3033. In: function In(k) {
  3034. return 1 - TWEEN.Easing.Bounce.Out(1 - k);
  3035. },
  3036. Out: function Out(k) {
  3037. if (k < 1 / 2.75) {
  3038. return 7.5625 * k * k;
  3039. } else if (k < 2 / 2.75) {
  3040. return 7.5625 * (k -= 1.5 / 2.75) * k + 0.75;
  3041. } else if (k < 2.5 / 2.75) {
  3042. return 7.5625 * (k -= 2.25 / 2.75) * k + 0.9375;
  3043. } else {
  3044. return 7.5625 * (k -= 2.625 / 2.75) * k + 0.984375;
  3045. }
  3046. },
  3047. InOut: function InOut(k) {
  3048. if (k < 0.5) {
  3049. return TWEEN.Easing.Bounce.In(k * 2) * 0.5;
  3050. }
  3051. return TWEEN.Easing.Bounce.Out(k * 2 - 1) * 0.5 + 0.5;
  3052. }
  3053. }
  3054. };
  3055. TWEEN.Interpolation = {
  3056. Linear: function Linear(v, k) {
  3057. var m = v.length - 1;
  3058. var f = m * k;
  3059. var i = Math.floor(f);
  3060. var fn = TWEEN.Interpolation.Utils.Linear;
  3061. if (k < 0) {
  3062. return fn(v[0], v[1], f);
  3063. }
  3064. if (k > 1) {
  3065. return fn(v[m], v[m - 1], m - f);
  3066. }
  3067. return fn(v[i], v[i + 1 > m ? m : i + 1], f - i);
  3068. },
  3069. Bezier: function Bezier(v, k) {
  3070. var b = 0;
  3071. var n = v.length - 1;
  3072. var pw = Math.pow;
  3073. var bn = TWEEN.Interpolation.Utils.Bernstein;
  3074. for (var i = 0; i <= n; i++) {
  3075. b += pw(1 - k, n - i) * pw(k, i) * v[i] * bn(n, i);
  3076. }
  3077. return b;
  3078. },
  3079. CatmullRom: function CatmullRom(v, k) {
  3080. var m = v.length - 1;
  3081. var f = m * k;
  3082. var i = Math.floor(f);
  3083. var fn = TWEEN.Interpolation.Utils.CatmullRom;
  3084. if (v[0] === v[m]) {
  3085. if (k < 0) {
  3086. i = Math.floor(f = m * (1 + k));
  3087. }
  3088. return fn(v[(i - 1 + m) % m], v[i], v[(i + 1) % m], v[(i + 2) % m], f - i);
  3089. } else {
  3090. if (k < 0) {
  3091. return v[0] - (fn(v[0], v[0], v[1], v[1], -f) - v[0]);
  3092. }
  3093. if (k > 1) {
  3094. return v[m] - (fn(v[m], v[m], v[m - 1], v[m - 1], f - m) - v[m]);
  3095. }
  3096. return fn(v[i ? i - 1 : 0], v[i], v[m < i + 1 ? m : i + 1], v[m < i + 2 ? m : i + 2], f - i);
  3097. }
  3098. },
  3099. Utils: {
  3100. Linear: function Linear(p0, p1, t) {
  3101. return (p1 - p0) * t + p0;
  3102. },
  3103. Bernstein: function Bernstein(n, i) {
  3104. var fc = TWEEN.Interpolation.Utils.Factorial;
  3105. return fc(n) / fc(i) / fc(n - i);
  3106. },
  3107. Factorial: function () {
  3108. var a = [1];
  3109. return function (n) {
  3110. var s = 1;
  3111. if (a[n]) {
  3112. return a[n];
  3113. }
  3114. for (var i = n; i > 1; i--) {
  3115. s *= i;
  3116. }
  3117. a[n] = s;
  3118. return s;
  3119. };
  3120. }(),
  3121. CatmullRom: function CatmullRom(p0, p1, p2, p3, t) {
  3122. var v0 = (p2 - p0) * 0.5;
  3123. var v1 = (p3 - p1) * 0.5;
  3124. var t2 = t * t;
  3125. var t3 = t * t2;
  3126. return (2 * p1 - 2 * p2 + v0 + v1) * t3 + (-3 * p1 + 3 * p2 - 2 * v0 - v1) * t2 + v0 * t + p1;
  3127. }
  3128. }
  3129. };
  3130. /**
  3131. * 根据2点获取角度
  3132. * @param Array [123, 23] 点1
  3133. * @param Array [123, 23] 点2
  3134. * @return angle 角度,不是弧度
  3135. */
  3136. function getAngle(start, end) {
  3137. var diff_x = end[0] - start[0];
  3138. var diff_y = end[1] - start[1];
  3139. var deg = 360 * Math.atan(diff_y / diff_x) / (2 * Math.PI);
  3140. if (end[0] < start[0]) {
  3141. deg = deg + 180;
  3142. }
  3143. return deg;
  3144. }
  3145. /**
  3146. * 绘制沿线箭头
  3147. * @author kyle / http://nikai.us/
  3148. */
  3149. var imageCache = {};
  3150. var object = {
  3151. draw: function draw(context, dataSet, options) {
  3152. // alert("绘制沿线箭头");
  3153. var imageCacheKey = 'http://huiyan.baidu.com/github/tools/gis-drawing/static/images/direction.png';
  3154. if (options.arrow && options.arrow.url) {
  3155. imageCacheKey = options.arrow.url;
  3156. }
  3157. if (!imageCache[imageCacheKey]) {
  3158. imageCache[imageCacheKey] = null;
  3159. }
  3160. var directionImage = imageCache[imageCacheKey];
  3161. if (!directionImage) {
  3162. var args = Array.prototype.slice.call(arguments);
  3163. var image = new Image();
  3164. image.onload = function () {
  3165. imageCache[imageCacheKey] = image;
  3166. object.draw.apply(null, args);
  3167. };
  3168. image.src = imageCacheKey;
  3169. return;
  3170. }
  3171. var data = dataSet instanceof DataSet ? dataSet.get() : dataSet;
  3172. // console.log('xxxx',options)
  3173. context.save();
  3174. for (var key in options) {
  3175. context[key] = options[key];
  3176. }
  3177. var points = [];
  3178. var preCoordinate = null;
  3179. for (var i = 0, len = data.length; i < len; i++) {
  3180. var item = data[i];
  3181. context.save();
  3182. if (item.fillStyle || item._fillStyle) {
  3183. context.fillStyle = item.fillStyle || item._fillStyle;
  3184. }
  3185. if (item.strokeStyle || item._strokeStyle) {
  3186. context.strokeStyle = item.strokeStyle || item._strokeStyle;
  3187. }
  3188. var type = item.geometry.type;
  3189. context.beginPath();
  3190. if (type === 'LineString') {
  3191. var coordinates = item.geometry._coordinates || item.geometry.coordinates;
  3192. var interval = options.arrow.interval !== undefined ? options.arrow.interval : 1;
  3193. for (var j = 0; j < coordinates.length; j += interval) {
  3194. if (coordinates[j] && coordinates[j + 1]) {
  3195. var coordinate = coordinates[j];
  3196. if (preCoordinate && getDistance(coordinate, preCoordinate) < 30) {
  3197. continue;
  3198. }
  3199. context.save();
  3200. var angle = getAngle(coordinates[j], coordinates[j + 1]);
  3201. context.translate(coordinate[0], coordinate[1]);
  3202. context.rotate(angle * Math.PI / 180);
  3203. context.drawImage(directionImage, -directionImage.width / 2 / 2, -directionImage.height / 2 / 2, directionImage.width / 2, directionImage.height / 2);
  3204. context.restore();
  3205. points.push(coordinate);
  3206. preCoordinate = coordinate;
  3207. }
  3208. }
  3209. }
  3210. context.restore();
  3211. }
  3212. context.restore();
  3213. }
  3214. };
  3215. function getDistance(coordinateA, coordinateB) {
  3216. return Math.sqrt(Math.pow(coordinateA[0] - coordinateB[0], 2) + Math.pow(coordinateA[1] - coordinateB[1], 2));
  3217. }
  3218. /**
  3219. * @author Mofei Zhu<mapv@zhuwenlong.com>
  3220. * This file is to draw text
  3221. */
  3222. var drawClip = {
  3223. draw: function draw(context, dataSet, options) {
  3224. var data = dataSet instanceof DataSet ? dataSet.get() : dataSet;
  3225. context.save();
  3226. // alert("drawClip");
  3227. context.fillStyle = options.fillStyle || 'rgba(0, 0, 0, 0.5)';
  3228. context.fillRect(0, 0, context.canvas.width, context.canvas.height);
  3229. options.multiPolygonDraw = function () {
  3230. context.save();
  3231. context.clip();
  3232. clear(context);
  3233. context.restore();
  3234. };
  3235. for (var i = 0, len = data.length; i < len; i++) {
  3236. context.beginPath();
  3237. pathSimple.drawDataSet(context, [data[i]], options);
  3238. context.save();
  3239. context.clip();
  3240. clear(context);
  3241. context.restore();
  3242. }
  3243. context.restore();
  3244. }
  3245. };
  3246. /**
  3247. * @author kyle / http://nikai.us/
  3248. */
  3249. var imageMap = {};
  3250. var stacks = {};
  3251. var drawCluster = {
  3252. draw: function draw(context, dataSet, options) {
  3253. context.save();
  3254. // alert("drawCluster");
  3255. var data = dataSet instanceof DataSet ? dataSet.get() : dataSet;
  3256. options.mapXown.graphicLayer.clear(true)
  3257. for (var i = 0; i < data.length; i++) {
  3258. var item = data[i];
  3259. var coordinates = item.geometry._coordinates || item.geometry.coordinates;
  3260. context.beginPath();
  3261. if (item.properties && item.properties.cluster) {
  3262. context.arc(coordinates[0], coordinates[1], item.size, 0, Math.PI * 2);
  3263. context.fillStyle = item.fillStyle;
  3264. context.fill();
  3265. if (options.label && options.label.show !== false) {
  3266. context.fillStyle = options.label.fillStyle || 'white';
  3267. if (options.label.font) {
  3268. context.font = options.label.font;
  3269. }
  3270. if (options.label.shadowColor) {
  3271. context.shadowColor = options.label.shadowColor;
  3272. }
  3273. if (options.label.shadowBlur) {
  3274. context.shadowBlur = options.label.shadowBlur;
  3275. }
  3276. var text = item.properties.point_count;
  3277. var textWidth = context.measureText(text).width;
  3278. context.fillText(text, coordinates[0] + 0.5 - textWidth / 2, coordinates[1] + 0.5 + 3);
  3279. }
  3280. } else {
  3281. if(!options.mapXownMapStatus){
  3282. // if(false){
  3283. this.drawIcon(item, options, context)
  3284. }else{
  3285. // console.log("333333333",options);
  3286. const graphic = new mars3d.graphic.DivGraphic({
  3287. id:item.camera_id? item.camera_id : "",
  3288. camera_id: item.camera_id? item.camera_id : "",
  3289. name: item.video_name ? item.video_name : "",
  3290. video_indexCode: item.video_indexCode ? item.video_indexCode : "",
  3291. video_name: item.video_name ? item.video_name : "",
  3292. video_status: item.video_status ? item.video_status : "",
  3293. video_type: item.video_type ? item.video_type : "",
  3294. positionto: item.positionto ? item.positionto : "",
  3295. position: item.geometry.coordinates,
  3296. hasZIndex: true,
  3297. style: {
  3298. html: ` <div class="mars3d-camera-content" >
  3299. <img class="mars3d-camera-img" src="img/icon/camera1.svg">
  3300. </div>`,
  3301. offsetX: -16, // 水平偏移
  3302. offsetY: -16, // 垂直偏移
  3303. distanceDisplayCondition: new Cesium.DistanceDisplayCondition(0, 100000)
  3304. },
  3305. popup: ``,
  3306. popupOptions: {
  3307. offsetY: -170, // 显示Popup的偏移值,是DivGraphic本身的像素高度值
  3308. template: ``,
  3309. horizontalOrigin: Cesium.HorizontalOrigin.LEFT,
  3310. verticalOrigin: Cesium.VerticalOrigin.CENTER
  3311. }
  3312. })
  3313. options.mapXown.graphicLayer.addGraphic(graphic)
  3314. graphic.on(mars3d.EventType.click, function (event) {
  3315. console.log('mapv.js', event);
  3316. options.mapXownClickEvent(event);
  3317. });
  3318. }
  3319. }
  3320. }
  3321. context.restore();
  3322. },
  3323. drawIcon: function drawIcon(item, options, context) {
  3324. var _ref = item.geometry._coordinates || item.geometry.coordinates,
  3325. _ref2 = slicedToArray(_ref, 2),
  3326. x = _ref2[0],
  3327. y = _ref2[1];
  3328. // alert("drawIcon");
  3329. var iconOptions = Object.assign({}, options.iconOptions, item.iconOptions);
  3330. var drawPoint = function drawPoint() {
  3331. context.beginPath();
  3332. context.arc(x, y, options.size || 5, 0, Math.PI * 2);
  3333. context.fillStyle = options.fillStyle || 'red';
  3334. context.fill();
  3335. };
  3336. if (!iconOptions.url) {
  3337. drawPoint();
  3338. return;
  3339. }
  3340. var iconWidth = iconOptions.width;
  3341. var iconHeight = iconOptions.height;
  3342. var iconOffset = iconOptions.offset || { x: 0, y: 0 };
  3343. x = x - ~~iconWidth / 2 + iconOffset.x;
  3344. y = y - ~~iconHeight / 2 + iconOffset.y;
  3345. var url = window.encodeURIComponent(iconOptions.url);
  3346. var img = imageMap[url];
  3347. if (img) {
  3348. if (img === 'error') {
  3349. drawPoint();
  3350. } else if (iconWidth && iconHeight) {
  3351. context.drawImage(img, x, y, iconWidth, iconHeight);
  3352. } else {
  3353. context.drawImage(img, x, y);
  3354. }
  3355. } else {
  3356. if (!stacks[url]) {
  3357. stacks[url] = [];
  3358. getImage(url, function (img, src) {
  3359. stacks[src] && stacks[src].forEach(function (fun) {
  3360. return fun(img);
  3361. });
  3362. stacks[src] = null;
  3363. imageMap[src] = img;
  3364. }, function (src) {
  3365. stacks[src] && stacks[src].forEach(function (fun) {
  3366. return fun('error', src);
  3367. });
  3368. stacks[src] = null;
  3369. imageMap[src] = 'error';
  3370. drawPoint();
  3371. });
  3372. }
  3373. stacks[url].push(function (x, y, iconWidth, iconHeight) {
  3374. return function (img) {
  3375. if (img === 'error') {
  3376. drawPoint();
  3377. } else if (iconWidth && iconHeight) {
  3378. context.drawImage(img, x, y, iconWidth, iconHeight);
  3379. } else {
  3380. context.drawImage(img, x, y);
  3381. }
  3382. };
  3383. }(x, y, iconWidth, iconHeight));
  3384. }
  3385. }
  3386. };
  3387. function getImage(url, callback, fallback) {
  3388. var img = new Image();
  3389. img.onload = function () {
  3390. callback && callback(img, url);
  3391. };
  3392. img.onerror = function () {
  3393. fallback && fallback(url);
  3394. };
  3395. img.src = window.decodeURIComponent(url);
  3396. }
  3397. /**
  3398. * @author Mofei Zhu<mapv@zhuwenlong.com>
  3399. * This file is to draw text
  3400. */
  3401. var drawText = {
  3402. draw: function draw(context, dataSet, options) {
  3403. var data = dataSet instanceof DataSet ? dataSet.get() : dataSet;
  3404. context.save();
  3405. // set from options
  3406. for (var key in options) {
  3407. context[key] = options[key];
  3408. }
  3409. var rects = [];
  3410. var size = options._size || options.size;
  3411. if (size) {
  3412. context.font = "bold " + size + "px Arial";
  3413. } else {
  3414. size = 12;
  3415. }
  3416. var textKey = options.textKey || 'text';
  3417. if (!options.textAlign) {
  3418. context.textAlign = 'center';
  3419. }
  3420. if (!options.textBaseline) {
  3421. context.textBaseline = 'middle';
  3422. }
  3423. if (options.avoid) {
  3424. // 标注避让
  3425. for (var i = 0, len = data.length; i < len; i++) {
  3426. var offset = data[i].offset || options.offset || {
  3427. x: 0,
  3428. y: 0
  3429. };
  3430. var coordinates = data[i].geometry._coordinates || data[i].geometry.coordinates;
  3431. var x = coordinates[0] + offset.x;
  3432. var y = coordinates[1] + offset.y;
  3433. var text = data[i][textKey];
  3434. var textWidth = context.measureText(text).width;
  3435. // 根据文本宽度和高度调整x,y位置,使得绘制文本时候坐标点在文本中心点,这个计算出的是左上角坐标
  3436. var px = x - textWidth / 2;
  3437. var py = y - size / 2;
  3438. var rect = {
  3439. sw: {
  3440. x: px,
  3441. y: py + size
  3442. },
  3443. ne: {
  3444. x: px + textWidth,
  3445. y: py
  3446. }
  3447. };
  3448. if (!hasOverlay(rects, rect)) {
  3449. rects.push(rect);
  3450. px = px + textWidth / 2;
  3451. py = py + size / 2;
  3452. context.fillText(text, px, py);
  3453. }
  3454. }
  3455. } else {
  3456. for (var i = 0, len = data.length; i < len; i++) {
  3457. var offset = data[i].offset || options.offset || {
  3458. x: 0,
  3459. y: 0
  3460. };
  3461. var coordinates = data[i].geometry._coordinates || data[i].geometry.coordinates;
  3462. var x = coordinates[0] + offset.x;
  3463. var y = coordinates[1] + offset.y;
  3464. var text = data[i][textKey];
  3465. context.fillText(text, x, y);
  3466. }
  3467. }
  3468. context.restore();
  3469. }
  3470. /*
  3471. * 当前文字区域和已有的文字区域是否有重叠部分
  3472. */
  3473. };function hasOverlay(rects, overlay) {
  3474. for (var i = 0; i < rects.length; i++) {
  3475. if (isRectOverlay(rects[i], overlay)) {
  3476. return true;
  3477. }
  3478. }
  3479. return false;
  3480. }
  3481. //判断2个矩形是否有重叠部分
  3482. function isRectOverlay(rect1, rect2) {
  3483. //minx、miny 2个矩形右下角最小的x和y
  3484. //maxx、maxy 2个矩形左上角最大的x和y
  3485. var minx = Math.min(rect1.ne.x, rect2.ne.x);
  3486. var miny = Math.min(rect1.sw.y, rect2.sw.y);
  3487. var maxx = Math.max(rect1.sw.x, rect2.sw.x);
  3488. var maxy = Math.max(rect1.ne.y, rect2.ne.y);
  3489. if (minx > maxx && miny > maxy) {
  3490. return true;
  3491. }
  3492. return false;
  3493. }
  3494. /**
  3495. * @author wanghyper
  3496. * This file is to draw icon
  3497. */
  3498. var imageMap$1 = {};
  3499. var stacks$1 = {};
  3500. var drawIcon = {
  3501. draw: function draw(context, dataSet, options) {
  3502. var data = dataSet instanceof DataSet ? dataSet.get() : dataSet;
  3503. var _loop = function _loop() {
  3504. var item = data[i];
  3505. if (item.geometry) {
  3506. icon = item.icon || options.icon;
  3507. if (typeof icon === 'string') {
  3508. var url = window.encodeURIComponent(icon);
  3509. var img = imageMap$1[url];
  3510. if (img) {
  3511. drawItem(img, options, context, item);
  3512. } else {
  3513. if (!stacks$1[url]) {
  3514. stacks$1[url] = [];
  3515. getImage$1(url, function (img, src) {
  3516. stacks$1[src] && stacks$1[src].forEach(function (fun) {
  3517. return fun(img);
  3518. });
  3519. stacks$1[src] = null;
  3520. imageMap$1[src] = img;
  3521. }, function (src) {
  3522. stacks$1[src] && stacks$1[src].forEach(function (fun) {
  3523. return fun('error');
  3524. });
  3525. stacks$1[src] = null;
  3526. imageMap$1[src] = 'error';
  3527. });
  3528. }
  3529. stacks$1[url].push(function (img) {
  3530. drawItem(img, options, context, item);
  3531. });
  3532. }
  3533. } else {
  3534. drawItem(icon, options, context, item);
  3535. }
  3536. }
  3537. };
  3538. for (var i = 0, len = data.length; i < len; i++) {
  3539. var icon;
  3540. _loop();
  3541. }
  3542. }
  3543. };
  3544. function drawItem(img, options, context, item) {
  3545. context.save();
  3546. var coordinates = item.geometry._coordinates || item.geometry.coordinates;
  3547. var x = coordinates[0];
  3548. var y = coordinates[1];
  3549. var offset = options.offset || { x: 0, y: 0 };
  3550. var width = item.width || options._width || options.width;
  3551. var height = item.height || options._height || options.height;
  3552. x = x - ~~width / 2 + offset.x;
  3553. y = y - ~~height / 2 + offset.y;
  3554. if (typeof img === 'string') {
  3555. context.beginPath();
  3556. context.arc(x, y, options.size || 5, 0, Math.PI * 2);
  3557. context.fillStyle = options.fillStyle || 'red';
  3558. context.fill();
  3559. return;
  3560. }
  3561. var deg = item.deg || options.deg;
  3562. if (deg) {
  3563. context.translate(x, y);
  3564. context.rotate(deg * Math.PI / 180);
  3565. context.translate(-x, -y);
  3566. }
  3567. if (options.sx && options.sy && options.swidth && options.sheight && options.width && options.height) {
  3568. context.drawImage(img, options.sx, options.sy, options.swidth, options.sheight, x, y, width, height);
  3569. } else if (width && height) {
  3570. context.drawImage(img, x, y, width, height);
  3571. } else {
  3572. context.drawImage(img, x, y);
  3573. }
  3574. context.restore();
  3575. }
  3576. function getImage$1(url, callback, fallback) {
  3577. var img = new Image();
  3578. img.onload = function () {
  3579. callback && callback(img, url);
  3580. };
  3581. img.onerror = function () {
  3582. fallback && fallback(url);
  3583. };
  3584. img.src = window.decodeURIComponent(url);
  3585. }
  3586. function sortKD(ids, coords, nodeSize, left, right, depth) {
  3587. if (right - left <= nodeSize) {
  3588. return;
  3589. }
  3590. var m = left + right >> 1;
  3591. select(ids, coords, m, left, right, depth % 2);
  3592. sortKD(ids, coords, nodeSize, left, m - 1, depth + 1);
  3593. sortKD(ids, coords, nodeSize, m + 1, right, depth + 1);
  3594. }
  3595. function select(ids, coords, k, left, right, inc) {
  3596. while (right > left) {
  3597. if (right - left > 600) {
  3598. var n = right - left + 1;
  3599. var m = k - left + 1;
  3600. var z = Math.log(n);
  3601. var s = 0.5 * Math.exp(2 * z / 3);
  3602. var sd = 0.5 * Math.sqrt(z * s * (n - s) / n) * (m - n / 2 < 0 ? -1 : 1);
  3603. var newLeft = Math.max(left, Math.floor(k - m * s / n + sd));
  3604. var newRight = Math.min(right, Math.floor(k + (n - m) * s / n + sd));
  3605. select(ids, coords, k, newLeft, newRight, inc);
  3606. }
  3607. var t = coords[2 * k + inc];
  3608. var i = left;
  3609. var j = right;
  3610. swapItem(ids, coords, left, k);
  3611. if (coords[2 * right + inc] > t) {
  3612. swapItem(ids, coords, left, right);
  3613. }
  3614. while (i < j) {
  3615. swapItem(ids, coords, i, j);
  3616. i++;
  3617. j--;
  3618. while (coords[2 * i + inc] < t) {
  3619. i++;
  3620. }
  3621. while (coords[2 * j + inc] > t) {
  3622. j--;
  3623. }
  3624. }
  3625. if (coords[2 * left + inc] === t) {
  3626. swapItem(ids, coords, left, j);
  3627. } else {
  3628. j++;
  3629. swapItem(ids, coords, j, right);
  3630. }
  3631. if (j <= k) {
  3632. left = j + 1;
  3633. }
  3634. if (k <= j) {
  3635. right = j - 1;
  3636. }
  3637. }
  3638. }
  3639. function swapItem(ids, coords, i, j) {
  3640. swap(ids, i, j);
  3641. swap(coords, 2 * i, 2 * j);
  3642. swap(coords, 2 * i + 1, 2 * j + 1);
  3643. }
  3644. function swap(arr, i, j) {
  3645. var tmp = arr[i];
  3646. arr[i] = arr[j];
  3647. arr[j] = tmp;
  3648. }
  3649. function range(ids, coords, minX, minY, maxX, maxY, nodeSize) {
  3650. var stack = [0, ids.length - 1, 0];
  3651. var result = [];
  3652. var x, y;
  3653. while (stack.length) {
  3654. var axis = stack.pop();
  3655. var right = stack.pop();
  3656. var left = stack.pop();
  3657. if (right - left <= nodeSize) {
  3658. for (var i = left; i <= right; i++) {
  3659. x = coords[2 * i];
  3660. y = coords[2 * i + 1];
  3661. if (x >= minX && x <= maxX && y >= minY && y <= maxY) {
  3662. result.push(ids[i]);
  3663. }
  3664. }
  3665. continue;
  3666. }
  3667. var m = Math.floor((left + right) / 2);
  3668. x = coords[2 * m];
  3669. y = coords[2 * m + 1];
  3670. if (x >= minX && x <= maxX && y >= minY && y <= maxY) {
  3671. result.push(ids[m]);
  3672. }
  3673. var nextAxis = (axis + 1) % 2;
  3674. if (axis === 0 ? minX <= x : minY <= y) {
  3675. stack.push(left);
  3676. stack.push(m - 1);
  3677. stack.push(nextAxis);
  3678. }
  3679. if (axis === 0 ? maxX >= x : maxY >= y) {
  3680. stack.push(m + 1);
  3681. stack.push(right);
  3682. stack.push(nextAxis);
  3683. }
  3684. }
  3685. return result;
  3686. }
  3687. function within(ids, coords, qx, qy, r, nodeSize) {
  3688. var stack = [0, ids.length - 1, 0];
  3689. var result = [];
  3690. var r2 = r * r;
  3691. while (stack.length) {
  3692. var axis = stack.pop();
  3693. var right = stack.pop();
  3694. var left = stack.pop();
  3695. if (right - left <= nodeSize) {
  3696. for (var i = left; i <= right; i++) {
  3697. if (sqDist(coords[2 * i], coords[2 * i + 1], qx, qy) <= r2) {
  3698. result.push(ids[i]);
  3699. }
  3700. }
  3701. continue;
  3702. }
  3703. var m = Math.floor((left + right) / 2);
  3704. var x = coords[2 * m];
  3705. var y = coords[2 * m + 1];
  3706. if (sqDist(x, y, qx, qy) <= r2) {
  3707. result.push(ids[m]);
  3708. }
  3709. var nextAxis = (axis + 1) % 2;
  3710. if (axis === 0 ? qx - r <= x : qy - r <= y) {
  3711. stack.push(left);
  3712. stack.push(m - 1);
  3713. stack.push(nextAxis);
  3714. }
  3715. if (axis === 0 ? qx + r >= x : qy + r >= y) {
  3716. stack.push(m + 1);
  3717. stack.push(right);
  3718. stack.push(nextAxis);
  3719. }
  3720. }
  3721. return result;
  3722. }
  3723. function sqDist(ax, ay, bx, by) {
  3724. var dx = ax - bx;
  3725. var dy = ay - by;
  3726. return dx * dx + dy * dy;
  3727. }
  3728. var defaultGetX = function defaultGetX(p) {
  3729. return p[0];
  3730. };
  3731. var defaultGetY = function defaultGetY(p) {
  3732. return p[1];
  3733. };
  3734. var KDBush = function KDBush(points, getX, getY, nodeSize, ArrayType) {
  3735. if (getX === void 0) getX = defaultGetX;
  3736. if (getY === void 0) getY = defaultGetY;
  3737. if (nodeSize === void 0) nodeSize = 64;
  3738. if (ArrayType === void 0) ArrayType = Float64Array;
  3739. this.nodeSize = nodeSize;
  3740. this.points = points;
  3741. var IndexArrayType = points.length < 65536 ? Uint16Array : Uint32Array;
  3742. var ids = this.ids = new IndexArrayType(points.length);
  3743. var coords = this.coords = new ArrayType(points.length * 2);
  3744. for (var i = 0; i < points.length; i++) {
  3745. ids[i] = i;
  3746. coords[2 * i] = getX(points[i]);
  3747. coords[2 * i + 1] = getY(points[i]);
  3748. }
  3749. sortKD(ids, coords, nodeSize, 0, ids.length - 1, 0);
  3750. };
  3751. KDBush.prototype.range = function range$1(minX, minY, maxX, maxY) {
  3752. return range(this.ids, this.coords, minX, minY, maxX, maxY, this.nodeSize);
  3753. };
  3754. KDBush.prototype.within = function within$1(x, y, r) {
  3755. return within(this.ids, this.coords, x, y, r, this.nodeSize);
  3756. };
  3757. var defaultOptions = {
  3758. minZoom: 0, // min zoom to generate clusters on
  3759. maxZoom: 16, // max zoom level to cluster the points on
  3760. minPoints: 2, // minimum points to form a cluster
  3761. radius: 40, // cluster radius in pixels
  3762. extent: 512, // tile extent (radius is calculated relative to it)
  3763. nodeSize: 64, // size of the KD-tree leaf node, affects performance
  3764. log: false, // whether to log timing info
  3765. // whether to generate numeric ids for input features (in vector tiles)
  3766. generateId: false,
  3767. // a reduce function for calculating custom cluster properties
  3768. reduce: null, // (accumulated, props) => { accumulated.sum += props.sum; }
  3769. // properties to use for individual points when running the reducer
  3770. map: function map(props) {
  3771. return props;
  3772. } // props => ({sum: props.my_value})
  3773. };
  3774. var Supercluster = function Supercluster(options) {
  3775. this.options = extend(Object.create(defaultOptions), options);
  3776. this.trees = new Array(this.options.maxZoom + 1);
  3777. };
  3778. Supercluster.prototype.load = function load(points) {
  3779. var ref = this.options;
  3780. var log = ref.log;
  3781. var minZoom = ref.minZoom;
  3782. var maxZoom = ref.maxZoom;
  3783. var nodeSize = ref.nodeSize;
  3784. if (log) {}
  3785. var timerId = "prepare " + points.length + " points";
  3786. if (log) {}
  3787. this.points = points;
  3788. // generate a cluster object for each point and index input points into a KD-tree
  3789. var clusters = [];
  3790. for (var i = 0; i < points.length; i++) {
  3791. if (!points[i].geometry) {
  3792. continue;
  3793. }
  3794. clusters.push(createPointCluster(points[i], i));
  3795. }
  3796. this.trees[maxZoom + 1] = new KDBush(clusters, getX, getY, nodeSize, Float32Array);
  3797. if (log) {}
  3798. // cluster points on max zoom, then cluster the results on previous zoom, etc.;
  3799. // results in a cluster hierarchy across zoom levels
  3800. for (var z = maxZoom; z >= minZoom; z--) {
  3801. var now = +Date.now();
  3802. // create a new set of clusters for the zoom and index them with a KD-tree
  3803. clusters = this._cluster(clusters, z);
  3804. this.trees[z] = new KDBush(clusters, getX, getY, nodeSize, Float32Array);
  3805. if (log) {}
  3806. }
  3807. if (log) {}
  3808. return this;
  3809. };
  3810. Supercluster.prototype.getClusters = function getClusters(bbox, zoom) {
  3811. var minLng = ((bbox[0] + 180) % 360 + 360) % 360 - 180;
  3812. var minLat = Math.max(-90, Math.min(90, bbox[1]));
  3813. var maxLng = bbox[2] === 180 ? 180 : ((bbox[2] + 180) % 360 + 360) % 360 - 180;
  3814. var maxLat = Math.max(-90, Math.min(90, bbox[3]));
  3815. if (bbox[2] - bbox[0] >= 360) {
  3816. minLng = -180;
  3817. maxLng = 180;
  3818. } else if (minLng > maxLng) {
  3819. var easternHem = this.getClusters([minLng, minLat, 180, maxLat], zoom);
  3820. var westernHem = this.getClusters([-180, minLat, maxLng, maxLat], zoom);
  3821. return easternHem.concat(westernHem);
  3822. }
  3823. var tree = this.trees[this._limitZoom(zoom)];
  3824. var ids = tree.range(lngX(minLng), latY(maxLat), lngX(maxLng), latY(minLat));
  3825. var clusters = [];
  3826. for (var i = 0, list = ids; i < list.length; i += 1) {
  3827. var id = list[i];
  3828. var c = tree.points[id];
  3829. clusters.push(c.numPoints ? getClusterJSON(c) : this.points[c.index]);
  3830. }
  3831. return clusters;
  3832. };
  3833. Supercluster.prototype.getChildren = function getChildren(clusterId) {
  3834. var originId = this._getOriginId(clusterId);
  3835. var originZoom = this._getOriginZoom(clusterId);
  3836. var errorMsg = 'No cluster with the specified id.';
  3837. var index = this.trees[originZoom];
  3838. if (!index) {
  3839. throw new Error(errorMsg);
  3840. }
  3841. var origin = index.points[originId];
  3842. if (!origin) {
  3843. throw new Error(errorMsg);
  3844. }
  3845. var r = this.options.radius / (this.options.extent * Math.pow(2, originZoom - 1));
  3846. var ids = index.within(origin.x, origin.y, r);
  3847. var children = [];
  3848. for (var i = 0, list = ids; i < list.length; i += 1) {
  3849. var id = list[i];
  3850. var c = index.points[id];
  3851. if (c.parentId === clusterId) {
  3852. children.push(c.numPoints ? getClusterJSON(c) : this.points[c.index]);
  3853. }
  3854. }
  3855. if (children.length === 0) {
  3856. throw new Error(errorMsg);
  3857. }
  3858. return children;
  3859. };
  3860. Supercluster.prototype.getLeaves = function getLeaves(clusterId, limit, offset) {
  3861. limit = limit || 10;
  3862. offset = offset || 0;
  3863. var leaves = [];
  3864. this._appendLeaves(leaves, clusterId, limit, offset, 0);
  3865. return leaves;
  3866. };
  3867. Supercluster.prototype.getTile = function getTile(z, x, y) {
  3868. var tree = this.trees[this._limitZoom(z)];
  3869. var z2 = Math.pow(2, z);
  3870. var ref = this.options;
  3871. var extent = ref.extent;
  3872. var radius = ref.radius;
  3873. var p = radius / extent;
  3874. var top = (y - p) / z2;
  3875. var bottom = (y + 1 + p) / z2;
  3876. var tile = {
  3877. features: []
  3878. };
  3879. this._addTileFeatures(tree.range((x - p) / z2, top, (x + 1 + p) / z2, bottom), tree.points, x, y, z2, tile);
  3880. if (x === 0) {
  3881. this._addTileFeatures(tree.range(1 - p / z2, top, 1, bottom), tree.points, z2, y, z2, tile);
  3882. }
  3883. if (x === z2 - 1) {
  3884. this._addTileFeatures(tree.range(0, top, p / z2, bottom), tree.points, -1, y, z2, tile);
  3885. }
  3886. return tile.features.length ? tile : null;
  3887. };
  3888. Supercluster.prototype.getClusterExpansionZoom = function getClusterExpansionZoom(clusterId) {
  3889. var expansionZoom = this._getOriginZoom(clusterId) - 1;
  3890. while (expansionZoom <= this.options.maxZoom) {
  3891. var children = this.getChildren(clusterId);
  3892. expansionZoom++;
  3893. if (children.length !== 1) {
  3894. break;
  3895. }
  3896. clusterId = children[0].properties.cluster_id;
  3897. }
  3898. return expansionZoom;
  3899. };
  3900. Supercluster.prototype._appendLeaves = function _appendLeaves(result, clusterId, limit, offset, skipped) {
  3901. var children = this.getChildren(clusterId);
  3902. for (var i = 0, list = children; i < list.length; i += 1) {
  3903. var child = list[i];
  3904. var props = child.properties;
  3905. if (props && props.cluster) {
  3906. if (skipped + props.point_count <= offset) {
  3907. // skip the whole cluster
  3908. skipped += props.point_count;
  3909. } else {
  3910. // enter the cluster
  3911. skipped = this._appendLeaves(result, props.cluster_id, limit, offset, skipped);
  3912. // exit the cluster
  3913. }
  3914. } else if (skipped < offset) {
  3915. // skip a single point
  3916. skipped++;
  3917. } else {
  3918. // add a single point
  3919. result.push(child);
  3920. }
  3921. if (result.length === limit) {
  3922. break;
  3923. }
  3924. }
  3925. return skipped;
  3926. };
  3927. Supercluster.prototype._addTileFeatures = function _addTileFeatures(ids, points, x, y, z2, tile) {
  3928. for (var i$1 = 0, list = ids; i$1 < list.length; i$1 += 1) {
  3929. var i = list[i$1];
  3930. var c = points[i];
  3931. var isCluster = c.numPoints;
  3932. var f = {
  3933. type: 1,
  3934. geometry: [[Math.round(this.options.extent * (c.x * z2 - x)), Math.round(this.options.extent * (c.y * z2 - y))]],
  3935. tags: isCluster ? getClusterProperties(c) : this.points[c.index].properties
  3936. };
  3937. // assign id
  3938. var id = void 0;
  3939. if (isCluster) {
  3940. id = c.id;
  3941. } else if (this.options.generateId) {
  3942. // optionally generate id
  3943. id = c.index;
  3944. } else if (this.points[c.index].id) {
  3945. // keep id if already assigned
  3946. id = this.points[c.index].id;
  3947. }
  3948. if (id !== undefined) {
  3949. f.id = id;
  3950. }
  3951. tile.features.push(f);
  3952. }
  3953. };
  3954. Supercluster.prototype._limitZoom = function _limitZoom(z) {
  3955. return Math.max(this.options.minZoom, Math.min(+z, this.options.maxZoom + 1));
  3956. };
  3957. Supercluster.prototype._cluster = function _cluster(points, zoom) {
  3958. var clusters = [];
  3959. var ref = this.options;
  3960. var radius = ref.radius;
  3961. var extent = ref.extent;
  3962. var reduce = ref.reduce;
  3963. var minPoints = ref.minPoints;
  3964. var r = radius / (extent * Math.pow(2, zoom));
  3965. // loop through each point
  3966. for (var i = 0; i < points.length; i++) {
  3967. var p = points[i];
  3968. // if we've already visited the point at this zoom level, skip it
  3969. if (p.zoom <= zoom) {
  3970. continue;
  3971. }
  3972. p.zoom = zoom;
  3973. // find all nearby points
  3974. var tree = this.trees[zoom + 1];
  3975. var neighborIds = tree.within(p.x, p.y, r);
  3976. var numPointsOrigin = p.numPoints || 1;
  3977. var numPoints = numPointsOrigin;
  3978. // count the number of points in a potential cluster
  3979. for (var i$1 = 0, list = neighborIds; i$1 < list.length; i$1 += 1) {
  3980. var neighborId = list[i$1];
  3981. var b = tree.points[neighborId];
  3982. // filter out neighbors that are already processed
  3983. if (b.zoom > zoom) {
  3984. numPoints += b.numPoints || 1;
  3985. }
  3986. }
  3987. if (numPoints >= minPoints) {
  3988. // enough points to form a cluster
  3989. var wx = p.x * numPointsOrigin;
  3990. var wy = p.y * numPointsOrigin;
  3991. var clusterProperties = reduce && numPointsOrigin > 1 ? this._map(p, true) : null;
  3992. // encode both zoom and point index on which the cluster originated -- offset by total length of features
  3993. var id = (i << 5) + (zoom + 1) + this.points.length;
  3994. for (var i$2 = 0, list$1 = neighborIds; i$2 < list$1.length; i$2 += 1) {
  3995. var neighborId$1 = list$1[i$2];
  3996. var b$1 = tree.points[neighborId$1];
  3997. if (b$1.zoom <= zoom) {
  3998. continue;
  3999. }
  4000. b$1.zoom = zoom; // save the zoom (so it doesn't get processed twice)
  4001. var numPoints2 = b$1.numPoints || 1;
  4002. wx += b$1.x * numPoints2; // accumulate coordinates for calculating weighted center
  4003. wy += b$1.y * numPoints2;
  4004. b$1.parentId = id;
  4005. if (reduce) {
  4006. if (!clusterProperties) {
  4007. clusterProperties = this._map(p, true);
  4008. }
  4009. reduce(clusterProperties, this._map(b$1));
  4010. }
  4011. }
  4012. p.parentId = id;
  4013. clusters.push(createCluster(wx / numPoints, wy / numPoints, id, numPoints, clusterProperties));
  4014. } else {
  4015. // left points as unclustered
  4016. clusters.push(p);
  4017. if (numPoints > 1) {
  4018. for (var i$3 = 0, list$2 = neighborIds; i$3 < list$2.length; i$3 += 1) {
  4019. var neighborId$2 = list$2[i$3];
  4020. var b$2 = tree.points[neighborId$2];
  4021. if (b$2.zoom <= zoom) {
  4022. continue;
  4023. }
  4024. b$2.zoom = zoom;
  4025. clusters.push(b$2);
  4026. }
  4027. }
  4028. }
  4029. }
  4030. return clusters;
  4031. };
  4032. // get index of the point from which the cluster originated
  4033. Supercluster.prototype._getOriginId = function _getOriginId(clusterId) {
  4034. return clusterId - this.points.length >> 5;
  4035. };
  4036. // get zoom of the point from which the cluster originated
  4037. Supercluster.prototype._getOriginZoom = function _getOriginZoom(clusterId) {
  4038. return (clusterId - this.points.length) % 32;
  4039. };
  4040. Supercluster.prototype._map = function _map(point, clone) {
  4041. if (point.numPoints) {
  4042. return clone ? extend({}, point.properties) : point.properties;
  4043. }
  4044. var original = this.points[point.index].properties;
  4045. var result = this.options.map(original);
  4046. return clone && result === original ? extend({}, result) : result;
  4047. };
  4048. function createCluster(x, y, id, numPoints, properties) {
  4049. return {
  4050. x: x, // weighted cluster center
  4051. y: y,
  4052. zoom: Infinity, // the last zoom the cluster was processed at
  4053. id: id, // encodes index of the first child of the cluster and its zoom level
  4054. parentId: -1, // parent cluster id
  4055. numPoints: numPoints,
  4056. properties: properties
  4057. };
  4058. }
  4059. function createPointCluster(p, id) {
  4060. var ref = p.geometry.coordinates;
  4061. var x = ref[0];
  4062. var y = ref[1];
  4063. return {
  4064. x: lngX(x), // projected point coordinates
  4065. y: latY(y),
  4066. zoom: Infinity, // the last zoom the point was processed at
  4067. index: id, // index of the source feature in the original input array,
  4068. parentId: -1 // parent cluster id
  4069. };
  4070. }
  4071. function getClusterJSON(cluster) {
  4072. return {
  4073. type: 'Feature',
  4074. id: cluster.id,
  4075. properties: getClusterProperties(cluster),
  4076. geometry: {
  4077. type: 'Point',
  4078. coordinates: [xLng(cluster.x), yLat(cluster.y)]
  4079. }
  4080. };
  4081. }
  4082. function getClusterProperties(cluster) {
  4083. var count = cluster.numPoints;
  4084. var abbrev = count >= 10000 ? Math.round(count / 1000) + "k" : count >= 1000 ? Math.round(count / 100) / 10 + "k" : count;
  4085. return extend(extend({}, cluster.properties), {
  4086. cluster: true,
  4087. cluster_id: cluster.id,
  4088. point_count: count,
  4089. point_count_abbreviated: abbrev
  4090. });
  4091. }
  4092. // longitude/latitude to spherical mercator in [0..1] range
  4093. function lngX(lng) {
  4094. return lng / 360 + 0.5;
  4095. }
  4096. function latY(lat) {
  4097. var sin = Math.sin(lat * Math.PI / 180);
  4098. var y = 0.5 - 0.25 * Math.log((1 + sin) / (1 - sin)) / Math.PI;
  4099. return y < 0 ? 0 : y > 1 ? 1 : y;
  4100. }
  4101. // spherical mercator to longitude/latitude
  4102. function xLng(x) {
  4103. return (x - 0.5) * 360;
  4104. }
  4105. function yLat(y) {
  4106. var y2 = (180 - y * 360) * Math.PI / 180;
  4107. return 360 * Math.atan(Math.exp(y2)) / Math.PI - 90;
  4108. }
  4109. function extend(dest, src) {
  4110. for (var id in src) {
  4111. dest[id] = src[id];
  4112. }
  4113. return dest;
  4114. }
  4115. function getX(p) {
  4116. return p.x;
  4117. }
  4118. function getY(p) {
  4119. return p.y;
  4120. }
  4121. /**
  4122. * @author kyle / http://nikai.us/
  4123. */
  4124. if (typeof window !== 'undefined') {
  4125. requestAnimationFrame(animate);
  4126. }
  4127. function animate(time) {
  4128. requestAnimationFrame(animate);
  4129. TWEEN.update(time);
  4130. }
  4131. var BaseLayer = function () {
  4132. function BaseLayer(map, dataSet, options) {
  4133. classCallCheck(this, BaseLayer);
  4134. if (!(dataSet instanceof DataSet)) {
  4135. dataSet = new DataSet(dataSet);
  4136. }
  4137. this.dataSet = dataSet;
  4138. this.map = map;
  4139. if (options.draw === 'cluster') {
  4140. this.refreshCluster(options);
  4141. }
  4142. }
  4143. createClass(BaseLayer, [{
  4144. key: 'refreshCluster',
  4145. value: function refreshCluster(options) {
  4146. options = options || this.options;
  4147. this.supercluster = new Supercluster({
  4148. maxZoom: options.maxZoom || 19,
  4149. radius: options.clusterRadius || 100,
  4150. minPoints: options.minPoints || 2,
  4151. extent: options.extent || 512
  4152. });
  4153. this.supercluster.load(this.dataSet.get());
  4154. // 拿到每个级别下的最大值最小值
  4155. this.supercluster.trees.forEach(function (item) {
  4156. var max = 0;
  4157. var min = Infinity;
  4158. item.points.forEach(function (point) {
  4159. max = Math.max(point.numPoints || 0, max);
  4160. min = Math.min(point.numPoints || Infinity, min);
  4161. });
  4162. item.max = max;
  4163. item.min = min;
  4164. });
  4165. this.clusterDataSet = new DataSet();
  4166. }
  4167. }, {
  4168. key: 'getDefaultContextConfig',
  4169. value: function getDefaultContextConfig() {
  4170. return {
  4171. globalAlpha: 1,
  4172. globalCompositeOperation: 'source-over',
  4173. imageSmoothingEnabled: true,
  4174. strokeStyle: '#000000',
  4175. fillStyle: '#000000',
  4176. shadowOffsetX: 0,
  4177. shadowOffsetY: 0,
  4178. shadowBlur: 0,
  4179. shadowColor: 'rgba(0, 0, 0, 0)',
  4180. lineWidth: 1,
  4181. lineCap: 'butt',
  4182. lineJoin: 'miter',
  4183. miterLimit: 10,
  4184. lineDashOffset: 0,
  4185. font: '10px sans-serif',
  4186. textAlign: 'start',
  4187. textBaseline: 'alphabetic'
  4188. };
  4189. }
  4190. }, {
  4191. key: 'initDataRange',
  4192. value: function initDataRange(options) {
  4193. var self = this;
  4194. self.intensity = new Intensity({
  4195. maxSize: self.options.maxSize,
  4196. minSize: self.options.minSize,
  4197. gradient: self.options.gradient,
  4198. max: self.options.max || this.dataSet.getMax('count')
  4199. });
  4200. self.category = new Category(self.options.splitList);
  4201. self.choropleth = new Choropleth(self.options.splitList);
  4202. if (self.options.splitList === undefined) {
  4203. self.category.generateByDataSet(this.dataSet, self.options.color);
  4204. }
  4205. if (self.options.splitList === undefined) {
  4206. var min = self.options.min || this.dataSet.getMin('count');
  4207. var max = self.options.max || this.dataSet.getMax('count');
  4208. self.choropleth.generateByMinMax(min, max);
  4209. }
  4210. }
  4211. }, {
  4212. key: 'getLegend',
  4213. value: function getLegend(options) {
  4214. var draw = this.options.draw;
  4215. var legend = null;
  4216. var self = this;
  4217. if (self.options.draw == 'intensity' || self.options.draw == 'heatmap') {
  4218. return this.intensity.getLegend(options);
  4219. } else if (self.options.draw == 'category') {
  4220. return this.category.getLegend(options);
  4221. }
  4222. }
  4223. }, {
  4224. key: 'processData',
  4225. value: function processData(data) {
  4226. var self = this;
  4227. var draw = self.options.draw;
  4228. if (draw == 'bubble' || draw == 'intensity' || draw == 'category' || draw == 'choropleth' || draw == 'simple') {
  4229. for (var i = 0; i < data.length; i++) {
  4230. var item = data[i];
  4231. if (self.options.draw == 'bubble') {
  4232. data[i]._size = self.intensity.getSize(item.count);
  4233. } else {
  4234. data[i]._size = undefined;
  4235. }
  4236. var styleType = '_fillStyle';
  4237. if (data[i].geometry.type === 'LineString' || self.options.styleType === 'stroke') {
  4238. styleType = '_strokeStyle';
  4239. }
  4240. if (self.options.draw == 'intensity') {
  4241. data[i][styleType] = self.intensity.getColor(item.count);
  4242. } else if (self.options.draw == 'category') {
  4243. data[i][styleType] = self.category.get(item.count);
  4244. } else if (self.options.draw == 'choropleth') {
  4245. data[i][styleType] = self.choropleth.get(item.count);
  4246. }
  4247. }
  4248. }
  4249. }
  4250. }, {
  4251. key: 'isEnabledTime',
  4252. value: function isEnabledTime() {
  4253. var animationOptions = this.options.animation;
  4254. var flag = animationOptions && !(animationOptions.enabled === false);
  4255. return flag;
  4256. }
  4257. }, {
  4258. key: 'argCheck',
  4259. value: function argCheck(options) {
  4260. if (options.draw == 'heatmap') {
  4261. if (options.strokeStyle) {
  4262. console.warn('[heatmap] options.strokeStyle is discard, pleause use options.strength [eg: options.strength = 0.1]');
  4263. }
  4264. }
  4265. }
  4266. }, {
  4267. key: 'drawContext',
  4268. value: function drawContext(context, dataSet, options, nwPixel) {
  4269. var self = this;
  4270. switch (self.options.draw) {
  4271. case 'heatmap':
  4272. drawHeatmap.draw(context, dataSet, self.options);
  4273. break;
  4274. case 'grid':
  4275. case 'cluster':
  4276. case 'honeycomb':
  4277. self.options.offset = {
  4278. x: nwPixel.x,
  4279. y: nwPixel.y
  4280. };
  4281. if (self.options.draw === 'grid') {
  4282. drawGrid.draw(context, dataSet, self.options);
  4283. } else if (self.options.draw === 'cluster') {
  4284. drawCluster.draw(context, dataSet, self.options);
  4285. } else {
  4286. drawHoneycomb.draw(context, dataSet, self.options);
  4287. }
  4288. break;
  4289. case 'text':
  4290. drawText.draw(context, dataSet, self.options);
  4291. break;
  4292. case 'icon':
  4293. drawIcon.draw(context, dataSet, self.options);
  4294. break;
  4295. case 'clip':
  4296. drawClip.draw(context, dataSet, self.options);
  4297. break;
  4298. default:
  4299. if (self.options.context == 'webgl') {
  4300. webglDrawSimple.draw(self.canvasLayer.canvas.getContext('webgl'), dataSet, self.options);
  4301. } else {
  4302. drawSimple.draw(context, dataSet, self.options);
  4303. }
  4304. }
  4305. if (self.options.arrow && self.options.arrow.show !== false) {
  4306. object.draw(context, dataSet, self.options);
  4307. }
  4308. }
  4309. }, {
  4310. key: 'isPointInPath',
  4311. value: function isPointInPath(context, pixel) {
  4312. var context = this.canvasLayer.canvas.getContext(this.context);
  4313. var data;
  4314. if (this.options.draw === 'cluster' && (!this.options.maxClusterZoom || this.options.maxClusterZoom >= this.getZoom())) {
  4315. data = this.clusterDataSet.get();
  4316. } else {
  4317. data = this.dataSet.get();
  4318. }
  4319. for (var i = 0; i < data.length; i++) {
  4320. context.beginPath();
  4321. var options = this.options;
  4322. var x = pixel.x * this.canvasLayer.devicePixelRatio;
  4323. var y = pixel.y * this.canvasLayer.devicePixelRatio;
  4324. options.multiPolygonDraw = function () {
  4325. if (context.isPointInPath(x, y)) {
  4326. return data[i];
  4327. }
  4328. };
  4329. pathSimple.draw(context, data[i], options);
  4330. var geoType = data[i].geometry && data[i].geometry.type;
  4331. if (geoType.indexOf('LineString') > -1) {
  4332. if (context.isPointInStroke && context.isPointInStroke(x, y)) {
  4333. return data[i];
  4334. }
  4335. } else {
  4336. if (context.isPointInPath(x, y)) {
  4337. return data[i];
  4338. }
  4339. }
  4340. }
  4341. }
  4342. // 递归获取聚合点下的所有原始点数据
  4343. }, {
  4344. key: 'getClusterPoints',
  4345. value: function getClusterPoints(cluster) {
  4346. var _this = this;
  4347. if (cluster.type !== 'Feature') {
  4348. return [];
  4349. }
  4350. var children = this.supercluster.getChildren(cluster.id);
  4351. return children.map(function (item) {
  4352. if (item.type === 'Feature') {
  4353. return _this.getClusterPoints(item);
  4354. } else {
  4355. return item;
  4356. }
  4357. }).flat();
  4358. }
  4359. }, {
  4360. key: 'clickEvent',
  4361. value: function clickEvent(pixel, e) {
  4362. if (!this.options.methods) {
  4363. return;
  4364. }
  4365. var dataItem = this.isPointInPath(this.getContext(), pixel);
  4366. if (dataItem) {
  4367. if (this.options.draw === 'cluster') {
  4368. var children = this.getClusterPoints(dataItem);
  4369. dataItem.children = children;
  4370. }
  4371. this.options.methods.click(dataItem, e);
  4372. } else {
  4373. this.options.methods.click(null, e);
  4374. }
  4375. }
  4376. }, {
  4377. key: 'mousemoveEvent',
  4378. value: function mousemoveEvent(pixel, e) {
  4379. if (!this.options.methods) {
  4380. return;
  4381. }
  4382. var dataItem = this.isPointInPath(this.getContext(), pixel);
  4383. if (dataItem) {
  4384. if (this.options.draw === 'cluster') {
  4385. var children = this.getClusterPoints(dataItem);
  4386. dataItem.children = children;
  4387. }
  4388. this.options.methods.mousemove(dataItem, e);
  4389. } else {
  4390. this.options.methods.mousemove(null, e);
  4391. }
  4392. }
  4393. }, {
  4394. key: 'tapEvent',
  4395. value: function tapEvent(pixel, e) {
  4396. if (!this.options.methods) {
  4397. return;
  4398. }
  4399. var dataItem = this.isPointInPath(this.getContext(), pixel);
  4400. if (dataItem) {
  4401. if (this.options.draw === 'cluster') {
  4402. var children = this.getClusterPoints(dataItem);
  4403. dataItem.children = children;
  4404. }
  4405. this.options.methods.tap(dataItem, e);
  4406. } else {
  4407. this.options.methods.tap(null, e);
  4408. }
  4409. }
  4410. /**
  4411. * obj.options
  4412. */
  4413. }, {
  4414. key: 'update',
  4415. value: function update(obj, isDraw) {
  4416. var self = this;
  4417. var _options = obj.options;
  4418. var options = self.options;
  4419. for (var i in _options) {
  4420. options[i] = _options[i];
  4421. }
  4422. self.init(options);
  4423. if (isDraw !== false) {
  4424. self.draw();
  4425. }
  4426. }
  4427. }, {
  4428. key: 'setOptions',
  4429. value: function setOptions(options) {
  4430. var self = this;
  4431. self.dataSet.reset();
  4432. // console.log('xxx1')
  4433. self.init(options);
  4434. // console.log('xxx')
  4435. self.draw();
  4436. }
  4437. }, {
  4438. key: 'set',
  4439. value: function set$$1(obj) {
  4440. var self = this;
  4441. var ctx = this.getContext();
  4442. var conf = this.getDefaultContextConfig();
  4443. for (var i in conf) {
  4444. ctx[i] = conf[i];
  4445. }
  4446. self.init(obj.options);
  4447. self.draw();
  4448. }
  4449. }, {
  4450. key: 'destroy',
  4451. value: function destroy() {
  4452. this.unbindEvent();
  4453. this.hide();
  4454. }
  4455. }, {
  4456. key: 'initAnimator',
  4457. value: function initAnimator() {
  4458. var self = this;
  4459. var animationOptions = self.options.animation;
  4460. if (self.options.draw == 'time' || self.isEnabledTime()) {
  4461. if (!animationOptions.stepsRange) {
  4462. animationOptions.stepsRange = {
  4463. start: this.dataSet.getMin('time') || 0,
  4464. end: this.dataSet.getMax('time') || 0
  4465. };
  4466. }
  4467. this.steps = { step: animationOptions.stepsRange.start };
  4468. self.animator = new TWEEN.Tween(this.steps).onUpdate(function () {
  4469. self._canvasUpdate(this.step);
  4470. }).repeat(Infinity);
  4471. this.addAnimatorEvent();
  4472. var duration = animationOptions.duration * 1000 || 5000;
  4473. self.animator.to({ step: animationOptions.stepsRange.end }, duration);
  4474. self.animator.start();
  4475. } else {
  4476. self.animator && self.animator.stop();
  4477. }
  4478. }
  4479. }, {
  4480. key: 'addAnimatorEvent',
  4481. value: function addAnimatorEvent() {}
  4482. }, {
  4483. key: 'animatorMovestartEvent',
  4484. value: function animatorMovestartEvent() {
  4485. var animationOptions = this.options.animation;
  4486. if (this.isEnabledTime() && this.animator) {
  4487. this.steps.step = animationOptions.stepsRange.start;
  4488. this.animator.stop();
  4489. }
  4490. }
  4491. }, {
  4492. key: 'animatorMoveendEvent',
  4493. value: function animatorMoveendEvent() {
  4494. if (this.isEnabledTime() && this.animator) {
  4495. this.animator.start();
  4496. }
  4497. }
  4498. }]);
  4499. return BaseLayer;
  4500. }();
  4501. var global$4 = typeof window === 'undefined' ? {} : window;
  4502. var BMap$2 = global$4.BMap || global$4.BMapGL;
  4503. var AnimationLayer = function (_BaseLayer) {
  4504. inherits(AnimationLayer, _BaseLayer);
  4505. function AnimationLayer(map, dataSet, options) {
  4506. classCallCheck(this, AnimationLayer);
  4507. var _this = possibleConstructorReturn(this, (AnimationLayer.__proto__ || Object.getPrototypeOf(AnimationLayer)).call(this, map, dataSet, options));
  4508. _this.map = map;
  4509. _this.options = options || {};
  4510. _this.dataSet = dataSet;
  4511. var canvasLayer = new CanvasLayer({
  4512. map: map,
  4513. zIndex: _this.options.zIndex,
  4514. update: _this._canvasUpdate.bind(_this)
  4515. });
  4516. _this.init(_this.options);
  4517. _this.canvasLayer = canvasLayer;
  4518. _this.transferToMercator();
  4519. var self = _this;
  4520. dataSet.on('change', function () {
  4521. self.transferToMercator();
  4522. canvasLayer.draw();
  4523. });
  4524. _this.ctx = canvasLayer.canvas.getContext('2d');
  4525. _this.start();
  4526. return _this;
  4527. }
  4528. createClass(AnimationLayer, [{
  4529. key: "draw",
  4530. value: function draw() {
  4531. this.canvasLayer.draw();
  4532. }
  4533. }, {
  4534. key: "init",
  4535. value: function init(options) {
  4536. var self = this;
  4537. self.options = options;
  4538. this.initDataRange(options);
  4539. this.context = self.options.context || '2d';
  4540. if (self.options.zIndex) {
  4541. this.canvasLayer && this.canvasLayer.setZIndex(self.options.zIndex);
  4542. }
  4543. if (self.options.max) {
  4544. this.intensity.setMax(self.options.max);
  4545. }
  4546. if (self.options.min) {
  4547. this.intensity.setMin(self.options.min);
  4548. }
  4549. this.initAnimator();
  4550. }
  4551. // 经纬度左边转换为墨卡托坐标
  4552. }, {
  4553. key: "transferToMercator",
  4554. value: function transferToMercator() {
  4555. var map = this.map;
  4556. var mapType = map.getMapType();
  4557. var projection;
  4558. if (mapType.getProjection) {
  4559. projection = mapType.getProjection();
  4560. } else {
  4561. projection = {
  4562. lngLatToPoint: function lngLatToPoint(point) {
  4563. var mc = map.lnglatToMercator(point.lng, point.lat);
  4564. return {
  4565. x: mc[0],
  4566. y: mc[1]
  4567. };
  4568. }
  4569. };
  4570. }
  4571. if (this.options.coordType !== 'bd09mc') {
  4572. var data = this.dataSet.get();
  4573. data = this.dataSet.transferCoordinate(data, function (coordinates) {
  4574. var pixel = projection.lngLatToPoint({
  4575. lng: coordinates[0],
  4576. lat: coordinates[1]
  4577. });
  4578. return [pixel.x, pixel.y];
  4579. }, 'coordinates', 'coordinates_mercator');
  4580. this.dataSet._set(data);
  4581. }
  4582. }
  4583. }, {
  4584. key: "_canvasUpdate",
  4585. value: function _canvasUpdate() {
  4586. var ctx = this.ctx;
  4587. if (!ctx) {
  4588. return;
  4589. }
  4590. //clear(ctx);
  4591. var map = this.map;
  4592. var projection;
  4593. var mcCenter;
  4594. if (map.getMapType().getProjection) {
  4595. projection = map.getMapType().getProjection();
  4596. mcCenter = projection.lngLatToPoint(map.getCenter());
  4597. } else {
  4598. mcCenter = {
  4599. x: map.getCenter().lng,
  4600. y: map.getCenter().lat
  4601. };
  4602. if (mcCenter.x > -180 && mcCenter.x < 180) {
  4603. mcCenter = map.lnglatToMercator(mcCenter.x, mcCenter.y);
  4604. mcCenter = { x: mcCenter[0], y: mcCenter[1] };
  4605. }
  4606. projection = {
  4607. lngLatToPoint: function lngLatToPoint(point) {
  4608. var mc = map.lnglatToMercator(point.lng, point.lat);
  4609. return {
  4610. x: mc[0],
  4611. y: mc[1]
  4612. };
  4613. }
  4614. };
  4615. }
  4616. var zoomUnit;
  4617. if (projection.getZoomUnits) {
  4618. zoomUnit = projection.getZoomUnits(map.getZoom());
  4619. } else {
  4620. zoomUnit = Math.pow(2, 18 - map.getZoom());
  4621. }
  4622. var nwMc = new BMap$2.Pixel(mcCenter.x - map.getSize().width / 2 * zoomUnit, mcCenter.y + map.getSize().height / 2 * zoomUnit); //左上角墨卡托坐标
  4623. clear(ctx);
  4624. var dataGetOptions = {
  4625. fromColumn: this.options.coordType == 'bd09mc' ? 'coordinates' : 'coordinates_mercator',
  4626. transferCoordinate: function transferCoordinate(coordinate) {
  4627. if (!coordinate) {
  4628. return;
  4629. }
  4630. var x = (coordinate[0] - nwMc.x) / zoomUnit;
  4631. var y = (nwMc.y - coordinate[1]) / zoomUnit;
  4632. return [x, y];
  4633. }
  4634. };
  4635. this.data = this.dataSet.get(dataGetOptions);
  4636. this.processData(this.data);
  4637. this.drawAnimation();
  4638. }
  4639. }, {
  4640. key: "drawAnimation",
  4641. value: function drawAnimation() {
  4642. var ctx = this.ctx;
  4643. var data = this.data;
  4644. if (!data) {
  4645. return;
  4646. }
  4647. ctx.save();
  4648. ctx.globalCompositeOperation = 'destination-out';
  4649. ctx.fillStyle = 'rgba(0, 0, 0, .1)';
  4650. ctx.fillRect(0, 0, ctx.canvas.width, ctx.canvas.height);
  4651. ctx.restore();
  4652. ctx.save();
  4653. if (this.options.shadowColor) {
  4654. ctx.shadowColor = this.options.shadowColor;
  4655. }
  4656. if (this.options.shadowBlur) {
  4657. ctx.shadowBlur = this.options.shadowBlur;
  4658. }
  4659. if (this.options.globalAlpha) {
  4660. ctx.globalAlpha = this.options.globalAlpha;
  4661. }
  4662. if (this.options.globalCompositeOperation) {
  4663. ctx.globalCompositeOperation = this.options.globalCompositeOperation;
  4664. }
  4665. var options = this.options;
  4666. for (var i = 0; i < data.length; i++) {
  4667. if (data[i].geometry.type === 'Point') {
  4668. ctx.beginPath();
  4669. var maxSize = data[i].size || this.options.size;
  4670. var minSize = data[i].minSize || this.options.minSize || 0;
  4671. if (data[i]._size === undefined) {
  4672. data[i]._size = minSize;
  4673. }
  4674. ctx.arc(data[i].geometry._coordinates[0], data[i].geometry._coordinates[1], data[i]._size, 0, Math.PI * 2, true);
  4675. ctx.closePath();
  4676. data[i]._size++;
  4677. if (data[i]._size > maxSize) {
  4678. data[i]._size = minSize;
  4679. }
  4680. ctx.lineWidth = 1;
  4681. ctx.strokeStyle = data[i].strokeStyle || data[i]._strokeStyle || options.strokeStyle || 'yellow';
  4682. ctx.stroke();
  4683. var fillStyle = data[i].fillStyle || data[i]._fillStyle || options.fillStyle;
  4684. if (fillStyle) {
  4685. ctx.fillStyle = fillStyle;
  4686. ctx.fill();
  4687. }
  4688. } else if (data[i].geometry.type === 'LineString') {
  4689. ctx.beginPath();
  4690. var size = data[i].size || this.options.size || 5;
  4691. var minSize = data[i].minSize || this.options.minSize || 0;
  4692. if (data[i]._index === undefined) {
  4693. data[i]._index = 0;
  4694. }
  4695. var index = data[i]._index;
  4696. ctx.arc(data[i].geometry._coordinates[index][0], data[i].geometry._coordinates[index][1], size, 0, Math.PI * 2, true);
  4697. ctx.closePath();
  4698. data[i]._index++;
  4699. if (data[i]._index >= data[i].geometry._coordinates.length) {
  4700. data[i]._index = 0;
  4701. }
  4702. var strokeStyle = data[i].strokeStyle || options.strokeStyle;
  4703. var fillStyle = data[i].fillStyle || options.fillStyle || 'yellow';
  4704. ctx.fillStyle = fillStyle;
  4705. ctx.fill();
  4706. if (strokeStyle && options.lineWidth) {
  4707. ctx.lineWidth = options.lineWidth || 1;
  4708. ctx.strokeStyle = strokeStyle;
  4709. ctx.stroke();
  4710. }
  4711. }
  4712. }
  4713. ctx.restore();
  4714. }
  4715. }, {
  4716. key: "animate",
  4717. value: function animate() {
  4718. this.drawAnimation();
  4719. var animateTime = this.options.animateTime || 100;
  4720. this.timeout = setTimeout(this.animate.bind(this), animateTime);
  4721. }
  4722. }, {
  4723. key: "start",
  4724. value: function start() {
  4725. this.stop();
  4726. this.animate();
  4727. }
  4728. }, {
  4729. key: "stop",
  4730. value: function stop() {
  4731. clearTimeout(this.timeout);
  4732. }
  4733. }, {
  4734. key: "unbindEvent",
  4735. value: function unbindEvent() {}
  4736. }, {
  4737. key: "hide",
  4738. value: function hide() {
  4739. this.canvasLayer.hide();
  4740. this.stop();
  4741. }
  4742. }, {
  4743. key: "show",
  4744. value: function show() {
  4745. this.start();
  4746. }
  4747. }, {
  4748. key: "clearData",
  4749. value: function clearData() {
  4750. this.dataSet && this.dataSet.clear();
  4751. this.update({
  4752. options: null
  4753. });
  4754. }
  4755. }, {
  4756. key: "destroy",
  4757. value: function destroy() {
  4758. this.stop();
  4759. this.unbindEvent();
  4760. this.clearData();
  4761. this.map.removeOverlay(this.canvasLayer);
  4762. this.canvasLayer = null;
  4763. }
  4764. }]);
  4765. return AnimationLayer;
  4766. }(BaseLayer);
  4767. /**
  4768. * @author kyle / http://nikai.us/
  4769. */
  4770. var global$5 = typeof window === 'undefined' ? {} : window;
  4771. var BMap$3 = global$5.BMap || global$5.BMapGL;
  4772. var Layer = function (_BaseLayer) {
  4773. inherits(Layer, _BaseLayer);
  4774. function Layer(map, dataSet, options) {
  4775. classCallCheck(this, Layer);
  4776. var _this = possibleConstructorReturn(this, (Layer.__proto__ || Object.getPrototypeOf(Layer)).call(this, map, dataSet, options));
  4777. var self = _this;
  4778. options = options || {};
  4779. _this.clickEvent = _this.clickEvent.bind(_this);
  4780. _this.mousemoveEvent = _this.mousemoveEvent.bind(_this);
  4781. _this.tapEvent = _this.tapEvent.bind(_this);
  4782. self.init(options);
  4783. self.argCheck(options);
  4784. self.transferToMercator();
  4785. var canvasLayer = _this.canvasLayer = new CanvasLayer({
  4786. map: map,
  4787. context: _this.context,
  4788. updateImmediate: options.updateImmediate,
  4789. paneName: options.paneName,
  4790. mixBlendMode: options.mixBlendMode,
  4791. enableMassClear: options.enableMassClear,
  4792. zIndex: options.zIndex,
  4793. update: function update() {
  4794. self._canvasUpdate();
  4795. }
  4796. });
  4797. dataSet.on('change', function () {
  4798. self.transferToMercator();
  4799. // 数据更新后重新生成聚合数据
  4800. if (options.draw === 'cluster') {
  4801. self.refreshCluster();
  4802. }
  4803. canvasLayer.draw();
  4804. });
  4805. return _this;
  4806. }
  4807. createClass(Layer, [{
  4808. key: 'clickEvent',
  4809. value: function clickEvent(e) {
  4810. var pixel = e.pixel;
  4811. get(Layer.prototype.__proto__ || Object.getPrototypeOf(Layer.prototype), 'clickEvent', this).call(this, pixel, e);
  4812. }
  4813. }, {
  4814. key: 'mousemoveEvent',
  4815. value: function mousemoveEvent(e) {
  4816. var pixel = e.pixel;
  4817. get(Layer.prototype.__proto__ || Object.getPrototypeOf(Layer.prototype), 'mousemoveEvent', this).call(this, pixel, e);
  4818. }
  4819. }, {
  4820. key: 'tapEvent',
  4821. value: function tapEvent(e) {
  4822. var pixel = e.pixel;
  4823. get(Layer.prototype.__proto__ || Object.getPrototypeOf(Layer.prototype), 'tapEvent', this).call(this, pixel, e);
  4824. }
  4825. }, {
  4826. key: 'bindEvent',
  4827. value: function bindEvent(e) {
  4828. this.unbindEvent();
  4829. var map = this.map;
  4830. var timer = 0;
  4831. var that = this;
  4832. if (this.options.methods) {
  4833. if (this.options.methods.click) {
  4834. map.setDefaultCursor('default');
  4835. map.addEventListener('click', this.clickEvent);
  4836. }
  4837. if (this.options.methods.mousemove) {
  4838. map.addEventListener('mousemove', this.mousemoveEvent);
  4839. }
  4840. if ('ontouchend' in window.document && this.options.methods.tap) {
  4841. map.addEventListener('touchstart', function (e) {
  4842. timer = new Date();
  4843. });
  4844. map.addEventListener('touchend', function (e) {
  4845. if (new Date() - timer < 300) {
  4846. that.tapEvent(e);
  4847. }
  4848. });
  4849. }
  4850. }
  4851. }
  4852. }, {
  4853. key: 'unbindEvent',
  4854. value: function unbindEvent(e) {
  4855. var map = this.map;
  4856. if (this.options.methods) {
  4857. if (this.options.methods.click) {
  4858. map.removeEventListener('click', this.clickEvent);
  4859. }
  4860. if (this.options.methods.mousemove) {
  4861. map.removeEventListener('mousemove', this.mousemoveEvent);
  4862. }
  4863. }
  4864. }
  4865. // 经纬度左边转换为墨卡托坐标
  4866. }, {
  4867. key: 'transferToMercator',
  4868. value: function transferToMercator(dataSet) {
  4869. if (!dataSet) {
  4870. dataSet = this.dataSet;
  4871. }
  4872. var map = this.map;
  4873. var mapType = map.getMapType();
  4874. var projection;
  4875. if (mapType.getProjection) {
  4876. projection = mapType.getProjection();
  4877. } else {
  4878. projection = {
  4879. lngLatToPoint: function lngLatToPoint(point) {
  4880. var mc = map.lnglatToMercator(point.lng, point.lat);
  4881. return {
  4882. x: mc[0],
  4883. y: mc[1]
  4884. };
  4885. }
  4886. };
  4887. }
  4888. if (this.options.coordType !== 'bd09mc') {
  4889. var data = dataSet.get();
  4890. data = dataSet.transferCoordinate(data, function (coordinates) {
  4891. if (coordinates[0] < -180 || coordinates[0] > 180 || coordinates[1] < -90 || coordinates[1] > 90) {
  4892. return coordinates;
  4893. } else {
  4894. var pixel = projection.lngLatToPoint({
  4895. lng: coordinates[0],
  4896. lat: coordinates[1]
  4897. });
  4898. return [pixel.x, pixel.y];
  4899. }
  4900. }, 'coordinates', 'coordinates_mercator');
  4901. dataSet._set(data);
  4902. }
  4903. }
  4904. }, {
  4905. key: 'getContext',
  4906. value: function getContext() {
  4907. return this.canvasLayer.canvas.getContext(this.context);
  4908. }
  4909. }, {
  4910. key: '_canvasUpdate',
  4911. value: function _canvasUpdate(time) {
  4912. if (!this.canvasLayer) {
  4913. return;
  4914. }
  4915. var self = this;
  4916. var animationOptions = this.options.animation;
  4917. var map = this.canvasLayer._map;
  4918. var projection;
  4919. var mcCenter;
  4920. if (map.getMapType().getProjection) {
  4921. projection = map.getMapType().getProjection();
  4922. mcCenter = projection.lngLatToPoint(map.getCenter());
  4923. } else {
  4924. mcCenter = {
  4925. x: map.getCenter().lng,
  4926. y: map.getCenter().lat
  4927. };
  4928. if (mcCenter.x > -180 && mcCenter.x < 180) {
  4929. mcCenter = map.lnglatToMercator(mcCenter.x, mcCenter.y);
  4930. mcCenter = { x: mcCenter[0], y: mcCenter[1] };
  4931. }
  4932. projection = {
  4933. lngLatToPoint: function lngLatToPoint(point) {
  4934. var mc = map.lnglatToMercator(point.lng, point.lat);
  4935. return {
  4936. x: mc[0],
  4937. y: mc[1]
  4938. };
  4939. }
  4940. };
  4941. }
  4942. var zoomUnit;
  4943. if (projection.getZoomUnits) {
  4944. zoomUnit = projection.getZoomUnits(map.getZoom());
  4945. } else {
  4946. zoomUnit = Math.pow(2, 18 - map.getZoom());
  4947. }
  4948. //左上角墨卡托坐标
  4949. var nwMc = new BMap$3.Pixel(mcCenter.x - map.getSize().width / 2 * zoomUnit, mcCenter.y + map.getSize().height / 2 * zoomUnit);
  4950. var context = this.getContext();
  4951. if (this.isEnabledTime()) {
  4952. if (time === undefined) {
  4953. clear(context);
  4954. return;
  4955. }
  4956. if (this.context == '2d') {
  4957. context.save();
  4958. context.globalCompositeOperation = 'destination-out';
  4959. context.fillStyle = 'rgba(0, 0, 0, .1)';
  4960. context.fillRect(0, 0, context.canvas.width, context.canvas.height);
  4961. context.restore();
  4962. }
  4963. } else {
  4964. clear(context);
  4965. }
  4966. if (this.context == '2d') {
  4967. for (var key in this.options) {
  4968. context[key] = this.options[key];
  4969. }
  4970. } else {
  4971. context.clear(context.COLOR_BUFFER_BIT);
  4972. }
  4973. if (this.options.minZoom && map.getZoom() < this.options.minZoom || this.options.maxZoom && map.getZoom() > this.options.maxZoom) {
  4974. return;
  4975. }
  4976. var scale = 1;
  4977. if (this.context != '2d') {
  4978. scale = this.canvasLayer.devicePixelRatio;
  4979. }
  4980. var dataGetOptions = {
  4981. fromColumn: this.options.coordType == 'bd09mc' ? 'coordinates' : 'coordinates_mercator',
  4982. transferCoordinate: function transferCoordinate(coordinate) {
  4983. var x = (coordinate[0] - nwMc.x) / zoomUnit * scale;
  4984. var y = (nwMc.y - coordinate[1]) / zoomUnit * scale;
  4985. return [x, y];
  4986. }
  4987. };
  4988. if (time !== undefined) {
  4989. dataGetOptions.filter = function (item) {
  4990. var trails = animationOptions.trails || 10;
  4991. if (time && item.time > time - trails && item.time < time) {
  4992. return true;
  4993. } else {
  4994. return false;
  4995. }
  4996. };
  4997. }
  4998. // get data from data set
  4999. var data;
  5000. var zoom = this.getZoom();
  5001. if (this.options.draw === 'cluster' && (!this.options.maxClusterZoom || this.options.maxClusterZoom >= zoom)) {
  5002. var bounds = this.map.getBounds();
  5003. var ne = bounds.getNorthEast();
  5004. var sw = bounds.getSouthWest();
  5005. var clusterData = this.supercluster.getClusters([sw.lng, sw.lat, ne.lng, ne.lat], zoom);
  5006. this.pointCountMax = this.supercluster.trees[zoom].max;
  5007. this.pointCountMin = this.supercluster.trees[zoom].min;
  5008. var intensity = {};
  5009. var color = null;
  5010. var size = null;
  5011. if (this.pointCountMax === this.pointCountMin) {
  5012. color = this.options.fillStyle;
  5013. size = this.options.minSize || 8;
  5014. } else {
  5015. intensity = new Intensity({
  5016. min: this.pointCountMin,
  5017. max: this.pointCountMax,
  5018. minSize: this.options.minSize || 8,
  5019. maxSize: this.options.maxSize || 30,
  5020. gradient: this.options.gradient
  5021. });
  5022. }
  5023. for (var i = 0; i < clusterData.length; i++) {
  5024. var item = clusterData[i];
  5025. if (item.properties && item.properties.cluster_id) {
  5026. clusterData[i].size = size || intensity.getSize(item.properties.point_count);
  5027. clusterData[i].fillStyle = color || intensity.getColor(item.properties.point_count);
  5028. } else {
  5029. clusterData[i].size = self.options.size;
  5030. }
  5031. }
  5032. this.clusterDataSet.set(clusterData);
  5033. this.transferToMercator(this.clusterDataSet);
  5034. data = self.clusterDataSet.get(dataGetOptions);
  5035. } else {
  5036. data = self.dataSet.get(dataGetOptions);
  5037. }
  5038. this.processData(data);
  5039. var nwPixel = map.pointToPixel(new BMap$3.Point(0, 0));
  5040. if (self.options.unit == 'm') {
  5041. if (self.options.size) {
  5042. self.options._size = self.options.size / zoomUnit;
  5043. }
  5044. if (self.options.width) {
  5045. self.options._width = self.options.width / zoomUnit;
  5046. }
  5047. if (self.options.height) {
  5048. self.options._height = self.options.height / zoomUnit;
  5049. }
  5050. } else {
  5051. self.options._size = self.options.size;
  5052. self.options._height = self.options.height;
  5053. self.options._width = self.options.width;
  5054. }
  5055. this.drawContext(context, data, self.options, nwPixel);
  5056. //console.timeEnd('draw');
  5057. //console.timeEnd('update')
  5058. self.options.updateCallback && self.options.updateCallback(time);
  5059. }
  5060. }, {
  5061. key: 'init',
  5062. value: function init(options) {
  5063. var self = this;
  5064. self.options = options;
  5065. this.initDataRange(options);
  5066. this.context = self.options.context || '2d';
  5067. if (self.options.zIndex) {
  5068. this.canvasLayer && this.canvasLayer.setZIndex(self.options.zIndex);
  5069. }
  5070. if (self.options.max) {
  5071. this.intensity.setMax(self.options.max);
  5072. }
  5073. if (self.options.min) {
  5074. this.intensity.setMin(self.options.min);
  5075. }
  5076. this.initAnimator();
  5077. this.bindEvent();
  5078. }
  5079. }, {
  5080. key: 'getZoom',
  5081. value: function getZoom() {
  5082. return this.map.getZoom();
  5083. }
  5084. }, {
  5085. key: 'addAnimatorEvent',
  5086. value: function addAnimatorEvent() {
  5087. this.map.addEventListener('movestart', this.animatorMovestartEvent.bind(this));
  5088. this.map.addEventListener('moveend', this.animatorMoveendEvent.bind(this));
  5089. }
  5090. }, {
  5091. key: 'show',
  5092. value: function show() {
  5093. this.map.addOverlay(this.canvasLayer);
  5094. this.bindEvent();
  5095. }
  5096. }, {
  5097. key: 'hide',
  5098. value: function hide() {
  5099. this.unbindEvent();
  5100. this.map.removeOverlay(this.canvasLayer);
  5101. }
  5102. }, {
  5103. key: 'draw',
  5104. value: function draw() {
  5105. this.canvasLayer && this.canvasLayer.draw();
  5106. }
  5107. }, {
  5108. key: 'clearData',
  5109. value: function clearData() {
  5110. this.dataSet && this.dataSet.clear();
  5111. this.update({
  5112. options: null
  5113. });
  5114. }
  5115. }, {
  5116. key: 'destroy',
  5117. value: function destroy() {
  5118. this.unbindEvent();
  5119. this.clearData();
  5120. this.map.removeOverlay(this.canvasLayer);
  5121. this.canvasLayer = null;
  5122. }
  5123. }]);
  5124. return Layer;
  5125. }(BaseLayer);
  5126. /**
  5127. * Copyright 2012 Google Inc. All Rights Reserved.
  5128. *
  5129. * Licensed under the Apache License, Version 2.0 (the "License");
  5130. * you may not use this file except in compliance with the License.
  5131. * You may obtain a copy of the License at
  5132. *
  5133. * http://www.apache.org/licenses/LICENSE-2.0
  5134. *
  5135. * Unless required by applicable law or agreed to in writing, software
  5136. * distributed under the License is distributed on an "AS IS" BASIS,
  5137. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  5138. * See the License for the specific language governing permissions and
  5139. * limitations under the License.
  5140. */
  5141. /**
  5142. * @fileoverview Extends OverlayView to provide a canvas "Layer".
  5143. * @author Brendan Kenny
  5144. */
  5145. /**
  5146. * A map layer that provides a canvas over the slippy map and a callback
  5147. * system for efficient animation. Requires canvas and CSS 2D transform
  5148. * support.
  5149. * @constructor
  5150. * @extends google.maps.OverlayView
  5151. * @param {CanvasLayerOptions=} opt_options Options to set in this CanvasLayer.
  5152. */
  5153. function CanvasLayer$2(opt_options) {
  5154. /**
  5155. * If true, canvas is in a map pane and the OverlayView is fully functional.
  5156. * See google.maps.OverlayView.onAdd for more information.
  5157. * @type {boolean}
  5158. * @private
  5159. */
  5160. this.isAdded_ = false;
  5161. /**
  5162. * If true, each update will immediately schedule the next.
  5163. * @type {boolean}
  5164. * @private
  5165. */
  5166. this.isAnimated_ = false;
  5167. /**
  5168. * The name of the MapPane in which this layer will be displayed.
  5169. * @type {string}
  5170. * @private
  5171. */
  5172. this.paneName_ = CanvasLayer$2.DEFAULT_PANE_NAME_;
  5173. /**
  5174. * A user-supplied function called whenever an update is required. Null or
  5175. * undefined if a callback is not provided.
  5176. * @type {?function=}
  5177. * @private
  5178. */
  5179. this.updateHandler_ = null;
  5180. /**
  5181. * A user-supplied function called whenever an update is required and the
  5182. * map has been resized since the last update. Null or undefined if a
  5183. * callback is not provided.
  5184. * @type {?function}
  5185. * @private
  5186. */
  5187. this.resizeHandler_ = null;
  5188. /**
  5189. * The LatLng coordinate of the top left of the current view of the map. Will
  5190. * be null when this.isAdded_ is false.
  5191. * @type {google.maps.LatLng}
  5192. * @private
  5193. */
  5194. this.topLeft_ = null;
  5195. /**
  5196. * The map-pan event listener. Will be null when this.isAdded_ is false. Will
  5197. * be null when this.isAdded_ is false.
  5198. * @type {?function}
  5199. * @private
  5200. */
  5201. this.centerListener_ = null;
  5202. /**
  5203. * The map-resize event listener. Will be null when this.isAdded_ is false.
  5204. * @type {?function}
  5205. * @private
  5206. */
  5207. this.resizeListener_ = null;
  5208. /**
  5209. * If true, the map size has changed and this.resizeHandler_ must be called
  5210. * on the next update.
  5211. * @type {boolean}
  5212. * @private
  5213. */
  5214. this.needsResize_ = true;
  5215. /**
  5216. * A browser-defined id for the currently requested callback. Null when no
  5217. * callback is queued.
  5218. * @type {?number}
  5219. * @private
  5220. */
  5221. this.requestAnimationFrameId_ = null;
  5222. var canvas = document.createElement('canvas');
  5223. canvas.style.position = 'absolute';
  5224. canvas.style.top = 0;
  5225. canvas.style.left = 0;
  5226. canvas.style.pointerEvents = 'none';
  5227. /**
  5228. * The canvas element.
  5229. * @type {!HTMLCanvasElement}
  5230. */
  5231. this.canvas = canvas;
  5232. /**
  5233. * The CSS width of the canvas, which may be different than the width of the
  5234. * backing store.
  5235. * @private {number}
  5236. */
  5237. this.canvasCssWidth_ = 300;
  5238. /**
  5239. * The CSS height of the canvas, which may be different than the height of
  5240. * the backing store.
  5241. * @private {number}
  5242. */
  5243. this.canvasCssHeight_ = 150;
  5244. /**
  5245. * A value for scaling the CanvasLayer resolution relative to the CanvasLayer
  5246. * display size.
  5247. * @private {number}
  5248. */
  5249. this.resolutionScale_ = 1;
  5250. /**
  5251. * Simple bind for functions with no args for bind-less browsers (Safari).
  5252. * @param {Object} thisArg The this value used for the target function.
  5253. * @param {function} func The function to be bound.
  5254. */
  5255. function simpleBindShim(thisArg, func) {
  5256. return function () {
  5257. func.apply(thisArg);
  5258. };
  5259. }
  5260. /**
  5261. * A reference to this.repositionCanvas_ with this bound as its this value.
  5262. * @type {function}
  5263. * @private
  5264. */
  5265. this.repositionFunction_ = simpleBindShim(this, this.repositionCanvas_);
  5266. /**
  5267. * A reference to this.resize_ with this bound as its this value.
  5268. * @type {function}
  5269. * @private
  5270. */
  5271. this.resizeFunction_ = simpleBindShim(this, this.resize_);
  5272. /**
  5273. * A reference to this.update_ with this bound as its this value.
  5274. * @type {function}
  5275. * @private
  5276. */
  5277. this.requestUpdateFunction_ = simpleBindShim(this, this.update_);
  5278. // set provided options, if any
  5279. if (opt_options) {
  5280. this.setOptions(opt_options);
  5281. }
  5282. }
  5283. var global$6 = typeof window === 'undefined' ? {} : window;
  5284. if (global$6.google && global$6.google.maps) {
  5285. CanvasLayer$2.prototype = new google.maps.OverlayView();
  5286. /**
  5287. * The default MapPane to contain the canvas.
  5288. * @type {string}
  5289. * @const
  5290. * @private
  5291. */
  5292. CanvasLayer$2.DEFAULT_PANE_NAME_ = 'overlayLayer';
  5293. /**
  5294. * Transform CSS property name, with vendor prefix if required. If browser
  5295. * does not support transforms, property will be ignored.
  5296. * @type {string}
  5297. * @const
  5298. * @private
  5299. */
  5300. CanvasLayer$2.CSS_TRANSFORM_ = function () {
  5301. var div = document.createElement('div');
  5302. var transformProps = ['transform', 'WebkitTransform', 'MozTransform', 'OTransform', 'msTransform'];
  5303. for (var i = 0; i < transformProps.length; i++) {
  5304. var prop = transformProps[i];
  5305. if (div.style[prop] !== undefined) {
  5306. return prop;
  5307. }
  5308. }
  5309. // return unprefixed version by default
  5310. return transformProps[0];
  5311. }();
  5312. /**
  5313. * The requestAnimationFrame function, with vendor-prefixed or setTimeout-based
  5314. * fallbacks. MUST be called with window as thisArg.
  5315. * @type {function}
  5316. * @param {function} callback The function to add to the frame request queue.
  5317. * @return {number} The browser-defined id for the requested callback.
  5318. * @private
  5319. */
  5320. CanvasLayer$2.prototype.requestAnimFrame_ = global$6.requestAnimationFrame || global$6.webkitRequestAnimationFrame || global$6.mozRequestAnimationFrame || global$6.oRequestAnimationFrame || global$6.msRequestAnimationFrame || function (callback) {
  5321. return global$6.setTimeout(callback, 1000 / 60);
  5322. };
  5323. /**
  5324. * The cancelAnimationFrame function, with vendor-prefixed fallback. Does not
  5325. * fall back to clearTimeout as some platforms implement requestAnimationFrame
  5326. * but not cancelAnimationFrame, and the cost is an extra frame on onRemove.
  5327. * MUST be called with window as thisArg.
  5328. * @type {function}
  5329. * @param {number=} requestId The id of the frame request to cancel.
  5330. * @private
  5331. */
  5332. CanvasLayer$2.prototype.cancelAnimFrame_ = global$6.cancelAnimationFrame || global$6.webkitCancelAnimationFrame || global$6.mozCancelAnimationFrame || global$6.oCancelAnimationFrame || global$6.msCancelAnimationFrame || function (requestId) {};
  5333. /**
  5334. * Sets any options provided. See CanvasLayerOptions for more information.
  5335. * @param {CanvasLayerOptions} options The options to set.
  5336. */
  5337. CanvasLayer$2.prototype.setOptions = function (options) {
  5338. if (options.animate !== undefined) {
  5339. this.setAnimate(options.animate);
  5340. }
  5341. if (options.paneName !== undefined) {
  5342. this.setPaneName(options.paneName);
  5343. }
  5344. if (options.updateHandler !== undefined) {
  5345. this.setUpdateHandler(options.updateHandler);
  5346. }
  5347. if (options.resizeHandler !== undefined) {
  5348. this.setResizeHandler(options.resizeHandler);
  5349. }
  5350. if (options.resolutionScale !== undefined) {
  5351. this.setResolutionScale(options.resolutionScale);
  5352. }
  5353. if (options.map !== undefined) {
  5354. this.setMap(options.map);
  5355. }
  5356. };
  5357. /**
  5358. * Set the animated state of the layer. If true, updateHandler will be called
  5359. * repeatedly, once per frame. If false, updateHandler will only be called when
  5360. * a map property changes that could require the canvas content to be redrawn.
  5361. * @param {boolean} animate Whether the canvas is animated.
  5362. */
  5363. CanvasLayer$2.prototype.setAnimate = function (animate) {
  5364. this.isAnimated_ = !!animate;
  5365. if (this.isAnimated_) {
  5366. this.scheduleUpdate();
  5367. }
  5368. };
  5369. /**
  5370. * @return {boolean} Whether the canvas is animated.
  5371. */
  5372. CanvasLayer$2.prototype.isAnimated = function () {
  5373. return this.isAnimated_;
  5374. };
  5375. /**
  5376. * Set the MapPane in which this layer will be displayed, by name. See
  5377. * {@code google.maps.MapPanes} for the panes available.
  5378. * @param {string} paneName The name of the desired MapPane.
  5379. */
  5380. CanvasLayer$2.prototype.setPaneName = function (paneName) {
  5381. this.paneName_ = paneName;
  5382. this.setPane_();
  5383. };
  5384. /**
  5385. * @return {string} The name of the current container pane.
  5386. */
  5387. CanvasLayer$2.prototype.getPaneName = function () {
  5388. return this.paneName_;
  5389. };
  5390. /**
  5391. * Adds the canvas to the specified container pane. Since this is guaranteed to
  5392. * execute only after onAdd is called, this is when paneName's existence is
  5393. * checked (and an error is thrown if it doesn't exist).
  5394. * @private
  5395. */
  5396. CanvasLayer$2.prototype.setPane_ = function () {
  5397. if (!this.isAdded_) {
  5398. return;
  5399. }
  5400. // onAdd has been called, so panes can be used
  5401. var panes = this.getPanes();
  5402. if (!panes[this.paneName_]) {
  5403. throw new Error('"' + this.paneName_ + '" is not a valid MapPane name.');
  5404. }
  5405. panes[this.paneName_].appendChild(this.canvas);
  5406. };
  5407. /**
  5408. * Set a function that will be called whenever the parent map and the overlay's
  5409. * canvas have been resized. If opt_resizeHandler is null or unspecified, any
  5410. * existing callback is removed.
  5411. * @param {?function=} opt_resizeHandler The resize callback function.
  5412. */
  5413. CanvasLayer$2.prototype.setResizeHandler = function (opt_resizeHandler) {
  5414. this.resizeHandler_ = opt_resizeHandler;
  5415. };
  5416. /**
  5417. * Sets a value for scaling the canvas resolution relative to the canvas
  5418. * display size. This can be used to save computation by scaling the backing
  5419. * buffer down, or to support high DPI devices by scaling it up (by e.g.
  5420. * window.devicePixelRatio).
  5421. * @param {number} scale
  5422. */
  5423. CanvasLayer$2.prototype.setResolutionScale = function (scale) {
  5424. if (typeof scale === 'number') {
  5425. this.resolutionScale_ = scale;
  5426. this.resize_();
  5427. }
  5428. };
  5429. /**
  5430. * Set a function that will be called when a repaint of the canvas is required.
  5431. * If opt_updateHandler is null or unspecified, any existing callback is
  5432. * removed.
  5433. * @param {?function=} opt_updateHandler The update callback function.
  5434. */
  5435. CanvasLayer$2.prototype.setUpdateHandler = function (opt_updateHandler) {
  5436. this.updateHandler_ = opt_updateHandler;
  5437. };
  5438. /**
  5439. * @inheritDoc
  5440. */
  5441. CanvasLayer$2.prototype.onAdd = function () {
  5442. if (this.isAdded_) {
  5443. return;
  5444. }
  5445. this.isAdded_ = true;
  5446. this.setPane_();
  5447. this.resizeListener_ = google.maps.event.addListener(this.getMap(), 'resize', this.resizeFunction_);
  5448. this.centerListener_ = google.maps.event.addListener(this.getMap(), 'center_changed', this.repositionFunction_);
  5449. this.resize_();
  5450. this.repositionCanvas_();
  5451. };
  5452. /**
  5453. * @inheritDoc
  5454. */
  5455. CanvasLayer$2.prototype.onRemove = function () {
  5456. if (!this.isAdded_) {
  5457. return;
  5458. }
  5459. this.isAdded_ = false;
  5460. this.topLeft_ = null;
  5461. // remove canvas and listeners for pan and resize from map
  5462. this.canvas.parentElement.removeChild(this.canvas);
  5463. if (this.centerListener_) {
  5464. google.maps.event.removeListener(this.centerListener_);
  5465. this.centerListener_ = null;
  5466. }
  5467. if (this.resizeListener_) {
  5468. google.maps.event.removeListener(this.resizeListener_);
  5469. this.resizeListener_ = null;
  5470. }
  5471. // cease canvas update callbacks
  5472. if (this.requestAnimationFrameId_) {
  5473. this.cancelAnimFrame_.call(global$6, this.requestAnimationFrameId_);
  5474. this.requestAnimationFrameId_ = null;
  5475. }
  5476. };
  5477. /**
  5478. * The internal callback for resize events that resizes the canvas to keep the
  5479. * map properly covered.
  5480. * @private
  5481. */
  5482. CanvasLayer$2.prototype.resize_ = function () {
  5483. if (!this.isAdded_) {
  5484. return;
  5485. }
  5486. var map = this.getMap();
  5487. var mapWidth = map.getDiv().offsetWidth;
  5488. var mapHeight = map.getDiv().offsetHeight;
  5489. var newWidth = mapWidth * this.resolutionScale_;
  5490. var newHeight = mapHeight * this.resolutionScale_;
  5491. var oldWidth = this.canvas.width;
  5492. var oldHeight = this.canvas.height;
  5493. // resizing may allocate a new back buffer, so do so conservatively
  5494. if (oldWidth !== newWidth || oldHeight !== newHeight) {
  5495. this.canvas.width = newWidth;
  5496. this.canvas.height = newHeight;
  5497. this.needsResize_ = true;
  5498. this.scheduleUpdate();
  5499. }
  5500. // reset styling if new sizes don't match; resize of data not needed
  5501. if (this.canvasCssWidth_ !== mapWidth || this.canvasCssHeight_ !== mapHeight) {
  5502. this.canvasCssWidth_ = mapWidth;
  5503. this.canvasCssHeight_ = mapHeight;
  5504. this.canvas.style.width = mapWidth + 'px';
  5505. this.canvas.style.height = mapHeight + 'px';
  5506. }
  5507. };
  5508. /**
  5509. * @inheritDoc
  5510. */
  5511. CanvasLayer$2.prototype.draw = function () {
  5512. this.repositionCanvas_();
  5513. };
  5514. /**
  5515. * Internal callback for map view changes. Since the Maps API moves the overlay
  5516. * along with the map, this function calculates the opposite translation to
  5517. * keep the canvas in place.
  5518. * @private
  5519. */
  5520. CanvasLayer$2.prototype.repositionCanvas_ = function () {
  5521. // TODO(bckenny): *should* only be executed on RAF, but in current browsers
  5522. // this causes noticeable hitches in map and overlay relative
  5523. // positioning.
  5524. var map = this.getMap();
  5525. // topLeft can't be calculated from map.getBounds(), because bounds are
  5526. // clamped to -180 and 180 when completely zoomed out. Instead, calculate
  5527. // left as an offset from the center, which is an unwrapped LatLng.
  5528. var top = map.getBounds().getNorthEast().lat();
  5529. var center = map.getCenter();
  5530. var scale = Math.pow(2, map.getZoom());
  5531. var left = center.lng() - this.canvasCssWidth_ * 180 / (256 * scale);
  5532. this.topLeft_ = new google.maps.LatLng(top, left);
  5533. // Canvas position relative to draggable map's container depends on
  5534. // overlayView's projection, not the map's. Have to use the center of the
  5535. // map for this, not the top left, for the same reason as above.
  5536. var projection = this.getProjection();
  5537. var divCenter = projection.fromLatLngToDivPixel(center);
  5538. var offsetX = -Math.round(this.canvasCssWidth_ / 2 - divCenter.x);
  5539. var offsetY = -Math.round(this.canvasCssHeight_ / 2 - divCenter.y);
  5540. this.canvas.style[CanvasLayer$2.CSS_TRANSFORM_] = 'translate(' + offsetX + 'px,' + offsetY + 'px)';
  5541. this.scheduleUpdate();
  5542. };
  5543. /**
  5544. * Internal callback that serves as main animation scheduler via
  5545. * requestAnimationFrame. Calls resize and update callbacks if set, and
  5546. * schedules the next frame if overlay is animated.
  5547. * @private
  5548. */
  5549. CanvasLayer$2.prototype.update_ = function () {
  5550. this.requestAnimationFrameId_ = null;
  5551. if (!this.isAdded_) {
  5552. return;
  5553. }
  5554. if (this.isAnimated_) {
  5555. this.scheduleUpdate();
  5556. }
  5557. if (this.needsResize_ && this.resizeHandler_) {
  5558. this.needsResize_ = false;
  5559. this.resizeHandler_();
  5560. }
  5561. if (this.updateHandler_) {
  5562. this.updateHandler_();
  5563. }
  5564. };
  5565. /**
  5566. * A convenience method to get the current LatLng coordinate of the top left of
  5567. * the current view of the map.
  5568. * @return {google.maps.LatLng} The top left coordinate.
  5569. */
  5570. CanvasLayer$2.prototype.getTopLeft = function () {
  5571. return this.topLeft_;
  5572. };
  5573. /**
  5574. * Schedule a requestAnimationFrame callback to updateHandler. If one is
  5575. * already scheduled, there is no effect.
  5576. */
  5577. CanvasLayer$2.prototype.scheduleUpdate = function () {
  5578. if (this.isAdded_ && !this.requestAnimationFrameId_) {
  5579. this.requestAnimationFrameId_ = this.requestAnimFrame_.call(global$6, this.requestUpdateFunction_);
  5580. }
  5581. };
  5582. }
  5583. /**
  5584. * @author kyle / http://nikai.us/
  5585. */
  5586. var Layer$2 = function (_BaseLayer) {
  5587. inherits(Layer, _BaseLayer);
  5588. function Layer(map, dataSet, options) {
  5589. classCallCheck(this, Layer);
  5590. var _this = possibleConstructorReturn(this, (Layer.__proto__ || Object.getPrototypeOf(Layer)).call(this, map, dataSet, options));
  5591. var self = _this;
  5592. var data = null;
  5593. options = options || {};
  5594. self.init(options);
  5595. self.argCheck(options);
  5596. var canvasLayerOptions = {
  5597. map: map,
  5598. animate: false,
  5599. updateHandler: function updateHandler() {
  5600. self._canvasUpdate();
  5601. },
  5602. resolutionScale: resolutionScale
  5603. };
  5604. var canvasLayer = _this.canvasLayer = new CanvasLayer$2(canvasLayerOptions);
  5605. _this.clickEvent = _this.clickEvent.bind(_this);
  5606. _this.mousemoveEvent = _this.mousemoveEvent.bind(_this);
  5607. _this.bindEvent();
  5608. return _this;
  5609. }
  5610. createClass(Layer, [{
  5611. key: "clickEvent",
  5612. value: function clickEvent(e) {
  5613. var pixel = e.pixel;
  5614. get(Layer.prototype.__proto__ || Object.getPrototypeOf(Layer.prototype), "clickEvent", this).call(this, pixel, e);
  5615. }
  5616. }, {
  5617. key: "mousemoveEvent",
  5618. value: function mousemoveEvent(e) {
  5619. var pixel = e.pixel;
  5620. get(Layer.prototype.__proto__ || Object.getPrototypeOf(Layer.prototype), "mousemoveEvent", this).call(this, pixel, e);
  5621. }
  5622. }, {
  5623. key: "bindEvent",
  5624. value: function bindEvent(e) {
  5625. var map = this.map;
  5626. if (this.options.methods) {
  5627. if (this.options.methods.click) {
  5628. map.setDefaultCursor("default");
  5629. map.addListener('click', this.clickEvent);
  5630. }
  5631. if (this.options.methods.mousemove) {
  5632. map.addListener('mousemove', this.mousemoveEvent);
  5633. }
  5634. }
  5635. }
  5636. }, {
  5637. key: "unbindEvent",
  5638. value: function unbindEvent(e) {
  5639. var map = this.map;
  5640. if (this.options.methods) {
  5641. if (this.options.methods.click) {
  5642. map.removeListener('click', this.clickEvent);
  5643. }
  5644. if (this.options.methods.mousemove) {
  5645. map.removeListener('mousemove', this.mousemoveEvent);
  5646. }
  5647. }
  5648. }
  5649. }, {
  5650. key: "getContext",
  5651. value: function getContext() {
  5652. return this.canvasLayer.canvas.getContext(this.context);
  5653. }
  5654. }, {
  5655. key: "_canvasUpdate",
  5656. value: function _canvasUpdate(time) {
  5657. if (!this.canvasLayer) {
  5658. return;
  5659. }
  5660. var self = this;
  5661. var animationOptions = self.options.animation;
  5662. var context = this.getContext();
  5663. if (self.isEnabledTime()) {
  5664. if (time === undefined) {
  5665. clear(context);
  5666. return;
  5667. }
  5668. if (this.context == '2d') {
  5669. context.save();
  5670. context.globalCompositeOperation = 'destination-out';
  5671. context.fillStyle = 'rgba(0, 0, 0, .1)';
  5672. context.fillRect(0, 0, context.canvas.width, context.canvas.height);
  5673. context.restore();
  5674. }
  5675. } else {
  5676. clear(context);
  5677. }
  5678. if (this.context == '2d') {
  5679. for (var key in self.options) {
  5680. context[key] = self.options[key];
  5681. }
  5682. } else {
  5683. context.clear(context.COLOR_BUFFER_BIT);
  5684. }
  5685. if (self.options.minZoom && map.getZoom() < self.options.minZoom || self.options.maxZoom && map.getZoom() > self.options.maxZoom) {
  5686. return;
  5687. }
  5688. var scale = 1;
  5689. if (this.context != '2d') {
  5690. scale = this.canvasLayer.devicePixelRatio;
  5691. }
  5692. var map = this.map;
  5693. var mapProjection = map.getProjection();
  5694. var scale = Math.pow(2, map.zoom) * resolutionScale;
  5695. var offset = mapProjection.fromLatLngToPoint(this.canvasLayer.getTopLeft());
  5696. var dataGetOptions = {
  5697. //fromColumn: self.options.coordType == 'bd09mc' ? 'coordinates' : 'coordinates_mercator',
  5698. transferCoordinate: function transferCoordinate(coordinate) {
  5699. var latLng = new google.maps.LatLng(coordinate[1], coordinate[0]);
  5700. var worldPoint = mapProjection.fromLatLngToPoint(latLng);
  5701. var pixel = {
  5702. x: (worldPoint.x - offset.x) * scale,
  5703. y: (worldPoint.y - offset.y) * scale
  5704. };
  5705. return [pixel.x, pixel.y];
  5706. }
  5707. };
  5708. if (time !== undefined) {
  5709. dataGetOptions.filter = function (item) {
  5710. var trails = animationOptions.trails || 10;
  5711. if (time && item.time > time - trails && item.time < time) {
  5712. return true;
  5713. } else {
  5714. return false;
  5715. }
  5716. };
  5717. }
  5718. // get data from data set
  5719. var data = self.dataSet.get(dataGetOptions);
  5720. this.processData(data);
  5721. var latLng = new google.maps.LatLng(0, 0);
  5722. var worldPoint = mapProjection.fromLatLngToPoint(latLng);
  5723. var pixel = {
  5724. x: (worldPoint.x - offset.x) * scale,
  5725. y: (worldPoint.y - offset.y) * scale
  5726. };
  5727. if (self.options.unit == 'm' && self.options.size) {
  5728. self.options._size = self.options.size / zoomUnit;
  5729. } else {
  5730. self.options._size = self.options.size;
  5731. }
  5732. this.drawContext(context, new DataSet(data), self.options, pixel);
  5733. //console.timeEnd('draw');
  5734. //console.timeEnd('update')
  5735. self.options.updateCallback && self.options.updateCallback(time);
  5736. }
  5737. }, {
  5738. key: "init",
  5739. value: function init(options) {
  5740. var self = this;
  5741. self.options = options;
  5742. this.initDataRange(options);
  5743. this.context = self.options.context || '2d';
  5744. if (self.options.zIndex) {
  5745. this.canvasLayer && this.canvasLayer.setZIndex(self.options.zIndex);
  5746. }
  5747. this.initAnimator();
  5748. }
  5749. }, {
  5750. key: "addAnimatorEvent",
  5751. value: function addAnimatorEvent() {
  5752. this.map.addListener('movestart', this.animatorMovestartEvent.bind(this));
  5753. this.map.addListener('moveend', this.animatorMoveendEvent.bind(this));
  5754. }
  5755. }, {
  5756. key: "show",
  5757. value: function show() {
  5758. this.map.addOverlay(this.canvasLayer);
  5759. }
  5760. }, {
  5761. key: "hide",
  5762. value: function hide() {
  5763. this.map.removeOverlay(this.canvasLayer);
  5764. }
  5765. }, {
  5766. key: "draw",
  5767. value: function draw() {
  5768. self.canvasLayer.draw();
  5769. }
  5770. }]);
  5771. return Layer;
  5772. }(BaseLayer);
  5773. /**
  5774. * MapV for maptalks.js (https://github.com/maptalks/maptalks.js)
  5775. * @author fuzhenn / https://github.com/fuzhenn
  5776. */
  5777. // import * as maptalks from 'maptalks';
  5778. var Layer$4 = void 0;
  5779. if (typeof maptalks !== 'undefined') {
  5780. Layer$4 = function (_maptalks$Layer) {
  5781. inherits(Layer, _maptalks$Layer);
  5782. function Layer(id, dataSet, options) {
  5783. classCallCheck(this, Layer);
  5784. var _this = possibleConstructorReturn(this, (Layer.__proto__ || Object.getPrototypeOf(Layer)).call(this, id, options));
  5785. _this.options_ = options;
  5786. _this.dataSet = dataSet;
  5787. _this._initBaseLayer(options);
  5788. return _this;
  5789. }
  5790. createClass(Layer, [{
  5791. key: "_initBaseLayer",
  5792. value: function _initBaseLayer(options) {
  5793. var self = this;
  5794. var baseLayer = this.baseLayer = new BaseLayer(null, this.dataSet, options);
  5795. self.init(options);
  5796. baseLayer.argCheck(options);
  5797. }
  5798. }, {
  5799. key: "clickEvent",
  5800. value: function clickEvent(e) {
  5801. if (!this.baseLayer) {
  5802. return;
  5803. }
  5804. var pixel = e.containerPoint;
  5805. this.baseLayer.clickEvent(pixel, e.domEvent);
  5806. }
  5807. }, {
  5808. key: "mousemoveEvent",
  5809. value: function mousemoveEvent(e) {
  5810. if (!this.baseLayer) {
  5811. return;
  5812. }
  5813. var pixel = e.containerPoint;
  5814. this.baseLayer.mousemoveEvent(pixel, e.domEvent);
  5815. }
  5816. }, {
  5817. key: "getEvents",
  5818. value: function getEvents() {
  5819. return {
  5820. 'click': this.clickEvent,
  5821. 'mousemove': this.mousemoveEvent
  5822. };
  5823. }
  5824. }, {
  5825. key: "init",
  5826. value: function init(options) {
  5827. var base = this.baseLayer;
  5828. base.options = options;
  5829. base.initDataRange(options);
  5830. base.context = base.options.context || '2d';
  5831. base.initAnimator();
  5832. }
  5833. }, {
  5834. key: "addAnimatorEvent",
  5835. value: function addAnimatorEvent() {
  5836. this.map.addListener('movestart', this.animatorMovestartEvent.bind(this));
  5837. this.map.addListener('moveend', this.animatorMoveendEvent.bind(this));
  5838. }
  5839. }]);
  5840. return Layer;
  5841. }(maptalks.Layer);
  5842. var LayerRenderer = function (_maptalks$renderer$Ca) {
  5843. inherits(LayerRenderer, _maptalks$renderer$Ca);
  5844. function LayerRenderer() {
  5845. classCallCheck(this, LayerRenderer);
  5846. return possibleConstructorReturn(this, (LayerRenderer.__proto__ || Object.getPrototypeOf(LayerRenderer)).apply(this, arguments));
  5847. }
  5848. createClass(LayerRenderer, [{
  5849. key: "needToRedraw",
  5850. value: function needToRedraw() {
  5851. var base = this.layer.baseLayer;
  5852. if (base.isEnabledTime()) {
  5853. return true;
  5854. }
  5855. return get(LayerRenderer.prototype.__proto__ || Object.getPrototypeOf(LayerRenderer.prototype), "needToRedraw", this).call(this);
  5856. }
  5857. }, {
  5858. key: "draw",
  5859. value: function draw() {
  5860. var base = this.layer.baseLayer;
  5861. if (!this.canvas || !base.isEnabledTime() || this._shouldClear) {
  5862. this.prepareCanvas();
  5863. this._shouldClear = false;
  5864. }
  5865. this._update(this.gl || this.context, this._mapvFrameTime);
  5866. delete this._mapvFrameTime;
  5867. this.completeRender();
  5868. }
  5869. }, {
  5870. key: "drawOnInteracting",
  5871. value: function drawOnInteracting() {
  5872. this.draw();
  5873. this._shouldClear = false;
  5874. }
  5875. }, {
  5876. key: "onSkipDrawOnInteracting",
  5877. value: function onSkipDrawOnInteracting() {
  5878. this._shouldClear = true;
  5879. }
  5880. }, {
  5881. key: "_canvasUpdate",
  5882. value: function _canvasUpdate(time) {
  5883. this.setToRedraw();
  5884. this._mapvFrameTime = time;
  5885. }
  5886. }, {
  5887. key: "_update",
  5888. value: function _update(context, time) {
  5889. if (!this.canvas) {
  5890. return;
  5891. }
  5892. var self = this.layer.baseLayer;
  5893. var animationOptions = self.options.animation;
  5894. var map = this.getMap();
  5895. if (self.isEnabledTime()) {
  5896. if (time === undefined) {
  5897. clear(context);
  5898. return;
  5899. }
  5900. if (self.context == '2d') {
  5901. context.save();
  5902. context.globalCompositeOperation = 'destination-out';
  5903. context.fillStyle = 'rgba(0, 0, 0, .1)';
  5904. context.fillRect(0, 0, context.canvas.width, context.canvas.height);
  5905. context.restore();
  5906. }
  5907. } else {
  5908. clear(context);
  5909. }
  5910. if (self.context == '2d') {
  5911. for (var key in self.options) {
  5912. context[key] = self.options[key];
  5913. }
  5914. } else {
  5915. context.clear(context.COLOR_BUFFER_BIT);
  5916. }
  5917. var scale = 1;
  5918. //reuse to save coordinate instance creation
  5919. var coord = new maptalks.Coordinate(0, 0);
  5920. var dataGetOptions = {
  5921. fromColumn: self.options.coordType === 'bd09mc' ? 'coordinates_mercator' : 'coordinates',
  5922. transferCoordinate: function transferCoordinate(coordinate) {
  5923. coord.x = coordinate[0];
  5924. coord.y = coordinate[1];
  5925. var r = map.coordToContainerPoint(coord)._multi(scale).toArray();
  5926. return r;
  5927. }
  5928. };
  5929. if (time !== undefined) {
  5930. dataGetOptions.filter = function (item) {
  5931. var trails = animationOptions.trails || 10;
  5932. if (time && item.time > time - trails && item.time < time) {
  5933. return true;
  5934. } else {
  5935. return false;
  5936. }
  5937. };
  5938. }
  5939. // get data from data set
  5940. var data = self.dataSet.get(dataGetOptions);
  5941. self.processData(data);
  5942. if (self.options.unit == 'm') {
  5943. if (self.options.size) {
  5944. self.options._size = self.options.size / zoomUnit;
  5945. }
  5946. if (self.options.width) {
  5947. self.options._width = self.options.width / zoomUnit;
  5948. }
  5949. if (self.options.height) {
  5950. self.options._height = self.options.height / zoomUnit;
  5951. }
  5952. } else {
  5953. self.options._size = self.options.size;
  5954. self.options._height = self.options.height;
  5955. self.options._width = self.options.width;
  5956. }
  5957. var zeroZero = new maptalks.Point(0, 0);
  5958. //screen position of the [0, 0] point
  5959. var zeroZeroScreen = map._pointToContainerPoint(zeroZero)._multi(scale);
  5960. self.drawContext(context, data, self.options, zeroZeroScreen);
  5961. //console.timeEnd('draw');
  5962. //console.timeEnd('update')
  5963. self.options.updateCallback && self.options.updateCallback(time);
  5964. }
  5965. }, {
  5966. key: "createCanvas",
  5967. value: function createCanvas() {
  5968. if (this.canvas) {
  5969. return;
  5970. }
  5971. var map = this.getMap();
  5972. var size = map.getSize();
  5973. var r = map.getDevicePixelRatio ? map.getDevicePixelRatio() : maptalks.Browser.retina ? 2 : 1,
  5974. w = r * size.width,
  5975. h = r * size.height;
  5976. this.canvas = maptalks.Canvas.createCanvas(w, h, map.CanvasClass);
  5977. var mapvContext = this.layer.baseLayer.context;
  5978. if (mapvContext === '2d') {
  5979. this.context = this.canvas.getContext('2d');
  5980. if (this.layer.options['globalCompositeOperation']) {
  5981. this.context.globalCompositeOperation = this.layer.options['globalCompositeOperation'];
  5982. }
  5983. if (this.layer.baseLayer.options.draw !== 'heatmap' && r !== 1) {
  5984. //in heatmap.js, devicePixelRatio is being mulitplied independently
  5985. this.context.scale(r, r);
  5986. }
  5987. } else {
  5988. var attributes = {
  5989. 'alpha': true,
  5990. 'preserveDrawingBuffer': true,
  5991. 'antialias': false
  5992. };
  5993. this.gl = this.canvas.getContext('webgl', attributes);
  5994. }
  5995. this.onCanvasCreate();
  5996. this._bindToMapv();
  5997. this.layer.fire('canvascreate', {
  5998. 'context': this.context,
  5999. 'gl': this.gl
  6000. });
  6001. }
  6002. }, {
  6003. key: "_bindToMapv",
  6004. value: function _bindToMapv() {
  6005. //some bindings needed by mapv baselayer
  6006. var base = this.layer.baseLayer;
  6007. var map = this.getMap();
  6008. this.devicePixelRatio = map.getDevicePixelRatio ? map.getDevicePixelRatio() : maptalks.Browser.retina ? 2 : 1;
  6009. base.canvasLayer = this;
  6010. base._canvasUpdate = this._canvasUpdate.bind(this);
  6011. base.getContext = function () {
  6012. var renderer = self.getRenderer();
  6013. return renderer.gl || renderer.context;
  6014. };
  6015. }
  6016. }]);
  6017. return LayerRenderer;
  6018. }(maptalks.renderer.CanvasRenderer);
  6019. Layer$4.registerRenderer('canvas', LayerRenderer);
  6020. }
  6021. var Layer$5 = Layer$4;
  6022. /**
  6023. * MapV for AMap
  6024. * @author sakitam-fdd - https://github.com/sakitam-fdd
  6025. */
  6026. /**
  6027. * create canvas
  6028. * @param width
  6029. * @param height
  6030. * @param Canvas
  6031. * @returns {HTMLCanvasElement}
  6032. */
  6033. var createCanvas = function createCanvas(width, height, Canvas) {
  6034. if (typeof document !== 'undefined') {
  6035. var canvas = document.createElement('canvas');
  6036. canvas.width = width;
  6037. canvas.height = height;
  6038. return canvas;
  6039. } else {
  6040. // create a new canvas instance in node.js
  6041. // the canvas class needs to have a default constructor without any parameter
  6042. return new Canvas(width, height);
  6043. }
  6044. };
  6045. var Layer$6 = function (_BaseLayer) {
  6046. inherits(Layer, _BaseLayer);
  6047. function Layer() {
  6048. var map = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : null;
  6049. var dataSet = arguments[1];
  6050. var options = arguments[2];
  6051. classCallCheck(this, Layer);
  6052. var _this = possibleConstructorReturn(this, (Layer.__proto__ || Object.getPrototypeOf(Layer)).call(this, map, dataSet, options));
  6053. _this.options = options;
  6054. /**
  6055. * internal
  6056. * @type {{canvas: null, devicePixelRatio: number}}
  6057. */
  6058. _this.canvasLayer = {
  6059. canvas: null,
  6060. devicePixelRatio: 1
  6061. };
  6062. /**
  6063. * canvas layer
  6064. * @type {null}
  6065. * @private
  6066. */
  6067. _this.layer_ = null;
  6068. _this.initDataRange(options);
  6069. _this.initAnimator();
  6070. _this.onEvents();
  6071. map.on('complete', function () {
  6072. this.init(map, options);
  6073. this.argCheck(options);
  6074. }, _this);
  6075. return _this;
  6076. }
  6077. /**
  6078. * init mapv layer
  6079. * @param map
  6080. * @param options
  6081. */
  6082. createClass(Layer, [{
  6083. key: "init",
  6084. value: function init(map, options) {
  6085. if (map) {
  6086. this.map = map;
  6087. this.context = this.options.context || '2d';
  6088. this.getCanvasLayer();
  6089. } else {
  6090. throw new Error('not map object');
  6091. }
  6092. }
  6093. /**
  6094. * update layer
  6095. * @param time
  6096. * @private
  6097. */
  6098. }, {
  6099. key: "_canvasUpdate",
  6100. value: function _canvasUpdate(time) {
  6101. this.render(this.canvasLayer.canvas, time);
  6102. }
  6103. /**
  6104. * render layer
  6105. * @param canvas
  6106. * @param time
  6107. * @returns {Layer}
  6108. */
  6109. }, {
  6110. key: "render",
  6111. value: function render(canvas, time) {
  6112. if (!canvas) return;
  6113. var map = this.map;
  6114. var context = canvas.getContext(this.context);
  6115. var animationOptions = this.options.animation;
  6116. if (this.isEnabledTime()) {
  6117. if (time === undefined) {
  6118. clear(context);
  6119. return this;
  6120. }
  6121. if (this.context === '2d') {
  6122. context.save();
  6123. context.globalCompositeOperation = 'destination-out';
  6124. context.fillStyle = 'rgba(0, 0, 0, .1)';
  6125. context.fillRect(0, 0, context.canvas.width, context.canvas.height);
  6126. context.restore();
  6127. }
  6128. } else {
  6129. clear(context);
  6130. }
  6131. if (this.context === '2d') {
  6132. for (var key in this.options) {
  6133. context[key] = this.options[key];
  6134. }
  6135. } else {
  6136. context.clear(context.COLOR_BUFFER_BIT);
  6137. }
  6138. var dataGetOptions = {
  6139. transferCoordinate: function transferCoordinate(coordinate) {
  6140. var _pixel = map.lngLatToContainer(new AMap.LngLat(coordinate[0], coordinate[1]));
  6141. return [_pixel['x'], _pixel['y']];
  6142. }
  6143. };
  6144. if (time !== undefined) {
  6145. dataGetOptions.filter = function (item) {
  6146. var trails = animationOptions.trails || 10;
  6147. if (time && item.time > time - trails && item.time < time) {
  6148. return true;
  6149. } else {
  6150. return false;
  6151. }
  6152. };
  6153. }
  6154. var data = this.dataSet.get(dataGetOptions);
  6155. this.processData(data);
  6156. if (this.options.unit === 'm') {
  6157. if (this.options.size) {
  6158. this.options._size = this.options.size / zoomUnit;
  6159. }
  6160. if (this.options.width) {
  6161. this.options._width = this.options.width / zoomUnit;
  6162. }
  6163. if (this.options.height) {
  6164. this.options._height = this.options.height / zoomUnit;
  6165. }
  6166. } else {
  6167. this.options._size = this.options.size;
  6168. this.options._height = this.options.height;
  6169. this.options._width = this.options.width;
  6170. }
  6171. this.drawContext(context, new DataSet(data), this.options, { x: 0, y: 0 });
  6172. this.options.updateCallback && this.options.updateCallback(time);
  6173. return this;
  6174. }
  6175. /**
  6176. * get canvas layer
  6177. */
  6178. }, {
  6179. key: "getCanvasLayer",
  6180. value: function getCanvasLayer() {
  6181. if (!this.canvasLayer.canvas && !this.layer_) {
  6182. var canvas = this.canvasFunction();
  6183. var bounds = this.map.getBounds();
  6184. this.layer_ = new AMap.CanvasLayer({
  6185. canvas: canvas,
  6186. bounds: this.options.bounds || bounds,
  6187. zooms: this.options.zooms || [0, 22]
  6188. });
  6189. this.layer_.setMap(this.map);
  6190. this.map.on('mapmove', this.canvasFunction, this);
  6191. this.map.on('zoomchange', this.canvasFunction, this);
  6192. }
  6193. }
  6194. /**
  6195. * canvas constructor
  6196. * @returns {*}
  6197. */
  6198. }, {
  6199. key: "canvasFunction",
  6200. value: function canvasFunction() {
  6201. var _ref = [this.map.getSize().width, this.map.getSize().height],
  6202. width = _ref[0],
  6203. height = _ref[1];
  6204. if (!this.canvasLayer.canvas) {
  6205. this.canvasLayer.canvas = createCanvas(width, height);
  6206. } else {
  6207. this.canvasLayer.canvas.width = width;
  6208. this.canvasLayer.canvas.height = height;
  6209. var bounds = this.map.getBounds();
  6210. if (this.layer_) {
  6211. this.layer_.setBounds(this.options.bounds || bounds);
  6212. }
  6213. }
  6214. this.render(this.canvasLayer.canvas);
  6215. return this.canvasLayer.canvas;
  6216. }
  6217. /**
  6218. * remove layer
  6219. */
  6220. }, {
  6221. key: "removeLayer",
  6222. value: function removeLayer() {
  6223. if (!this.map) return;
  6224. this.unEvents();
  6225. this.map.removeLayer(this.layer_);
  6226. delete this.map;
  6227. delete this.layer_;
  6228. delete this.canvasLayer.canvas;
  6229. }
  6230. }, {
  6231. key: "getContext",
  6232. value: function getContext() {
  6233. return this.canvasLayer.canvas.getContext(this.context);
  6234. }
  6235. /**
  6236. * handle click event
  6237. * @param event
  6238. */
  6239. }, {
  6240. key: "clickEvent",
  6241. value: function clickEvent(event) {
  6242. var pixel = event.pixel;
  6243. get(Layer.prototype.__proto__ || Object.getPrototypeOf(Layer.prototype), "clickEvent", this).call(this, pixel, event);
  6244. }
  6245. /**
  6246. * handle mousemove/pointermove event
  6247. * @param event
  6248. */
  6249. }, {
  6250. key: "mousemoveEvent",
  6251. value: function mousemoveEvent(event) {
  6252. var pixel = event.pixel;
  6253. get(Layer.prototype.__proto__ || Object.getPrototypeOf(Layer.prototype), "mousemoveEvent", this).call(this, pixel, event);
  6254. }
  6255. /**
  6256. * add animator event
  6257. */
  6258. }, {
  6259. key: "addAnimatorEvent",
  6260. value: function addAnimatorEvent() {
  6261. this.map.on('movestart', this.animatorMovestartEvent, this);
  6262. this.map.on('moveend', this.animatorMoveendEvent, this);
  6263. }
  6264. /**
  6265. * bind event
  6266. */
  6267. }, {
  6268. key: "onEvents",
  6269. value: function onEvents() {
  6270. var map = this.map;
  6271. this.unEvents();
  6272. if (this.options.methods) {
  6273. if (this.options.methods.click) {
  6274. map.on('click', this.clickEvent, this);
  6275. }
  6276. if (this.options.methods.mousemove) {
  6277. map.on('mousemove', this.mousemoveEvent, this);
  6278. }
  6279. }
  6280. }
  6281. /**
  6282. * unbind events
  6283. */
  6284. }, {
  6285. key: "unEvents",
  6286. value: function unEvents() {
  6287. var map = this.map;
  6288. if (this.options.methods) {
  6289. if (this.options.methods.click) {
  6290. map.off('click', this.clickEvent, this);
  6291. }
  6292. if (this.options.methods.mousemove) {
  6293. map.off('mousemove', this.mousemoveEvent, this);
  6294. }
  6295. }
  6296. }
  6297. }]);
  6298. return Layer;
  6299. }(BaseLayer);
  6300. /**
  6301. * MapV for openlayers (https://openlayers.org)
  6302. * @author sakitam-fdd - https://github.com/sakitam-fdd
  6303. */
  6304. /**
  6305. * create canvas
  6306. * @param width
  6307. * @param height
  6308. * @returns {HTMLCanvasElement}
  6309. */
  6310. var createCanvas$1 = function createCanvas(width, height) {
  6311. if (typeof document !== 'undefined') {
  6312. var canvas = document.createElement('canvas');
  6313. canvas.width = width;
  6314. canvas.height = height;
  6315. return canvas;
  6316. } else {
  6317. // create a new canvas instance in node.js
  6318. // the canvas class needs to have a default constructor without any parameter
  6319. }
  6320. };
  6321. var Layer$8 = function (_BaseLayer) {
  6322. inherits(Layer, _BaseLayer);
  6323. function Layer() {
  6324. var map = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : null;
  6325. var dataSet = arguments[1];
  6326. var options = arguments[2];
  6327. classCallCheck(this, Layer);
  6328. var _this = possibleConstructorReturn(this, (Layer.__proto__ || Object.getPrototypeOf(Layer)).call(this, map, dataSet, options));
  6329. _this.options = options;
  6330. /**
  6331. * internal
  6332. * @type {{canvas: null, devicePixelRatio: number}}
  6333. */
  6334. _this.canvasLayer = {
  6335. canvas: null,
  6336. devicePixelRatio: 1
  6337. /**
  6338. * cavnas layer
  6339. * @type {null}
  6340. * @private
  6341. */
  6342. };_this.layer_ = null;
  6343. /**
  6344. * previous cursor
  6345. * @type {undefined}
  6346. * @private
  6347. */
  6348. _this.previousCursor_ = undefined;
  6349. _this.init(map, options);
  6350. _this.argCheck(options);
  6351. return _this;
  6352. }
  6353. /**
  6354. * init mapv layer
  6355. * @param map
  6356. * @param options
  6357. */
  6358. createClass(Layer, [{
  6359. key: "init",
  6360. value: function init(map, options) {
  6361. if (map && map instanceof ol.Map) {
  6362. this.$Map = map;
  6363. this.context = this.options.context || '2d';
  6364. this.getCanvasLayer();
  6365. this.initDataRange(options);
  6366. this.initAnimator();
  6367. this.onEvents();
  6368. } else {
  6369. throw new Error('not map object');
  6370. }
  6371. }
  6372. /**
  6373. * update layer
  6374. * @param time
  6375. * @private
  6376. */
  6377. }, {
  6378. key: "_canvasUpdate",
  6379. value: function _canvasUpdate(time) {
  6380. this.render(this.canvasLayer.canvas, time);
  6381. }
  6382. /**
  6383. * render layer
  6384. * @param canvas
  6385. * @param time
  6386. * @returns {Layer}
  6387. */
  6388. }, {
  6389. key: "render",
  6390. value: function render(canvas, time) {
  6391. var map = this.$Map;
  6392. var context = canvas.getContext(this.context);
  6393. var animationOptions = this.options.animation;
  6394. var _projection = this.options.hasOwnProperty('projection') ? this.options.projection : 'EPSG:4326';
  6395. var mapViewProjection = this.$Map.getView().getProjection().getCode();
  6396. if (this.isEnabledTime()) {
  6397. if (time === undefined) {
  6398. clear(context);
  6399. return this;
  6400. }
  6401. if (this.context === '2d') {
  6402. context.save();
  6403. context.globalCompositeOperation = 'destination-out';
  6404. context.fillStyle = 'rgba(0, 0, 0, .1)';
  6405. context.fillRect(0, 0, context.canvas.width, context.canvas.height);
  6406. context.restore();
  6407. }
  6408. } else {
  6409. clear(context);
  6410. }
  6411. if (this.context === '2d') {
  6412. for (var key in this.options) {
  6413. context[key] = this.options[key];
  6414. }
  6415. } else {
  6416. context.clear(context.COLOR_BUFFER_BIT);
  6417. }
  6418. var dataGetOptions = {};
  6419. dataGetOptions.transferCoordinate = _projection === mapViewProjection ? function (coordinate) {
  6420. // 当数据与map的投影一致时不再进行投影转换
  6421. return map.getPixelFromCoordinate(coordinate);
  6422. } : function (coordinate) {
  6423. // 数据与Map投影不一致时 将数据投影转换为 Map的投影
  6424. return map.getPixelFromCoordinate(ol.proj.transform(coordinate, _projection, mapViewProjection));
  6425. };
  6426. if (time !== undefined) {
  6427. dataGetOptions.filter = function (item) {
  6428. var trails = animationOptions.trails || 10;
  6429. if (time && item.time > time - trails && item.time < time) {
  6430. return true;
  6431. } else {
  6432. return false;
  6433. }
  6434. };
  6435. }
  6436. var data = this.dataSet.get(dataGetOptions);
  6437. this.processData(data);
  6438. if (this.options.unit === 'm') {
  6439. if (this.options.size) {
  6440. this.options._size = this.options.size / zoomUnit;
  6441. }
  6442. if (this.options.width) {
  6443. this.options._width = this.options.width / zoomUnit;
  6444. }
  6445. if (this.options.height) {
  6446. this.options._height = this.options.height / zoomUnit;
  6447. }
  6448. } else {
  6449. this.options._size = this.options.size;
  6450. this.options._height = this.options.height;
  6451. this.options._width = this.options.width;
  6452. }
  6453. this.drawContext(context, new DataSet(data), this.options, { x: 0, y: 0 });
  6454. this.options.updateCallback && this.options.updateCallback(time);
  6455. return this;
  6456. }
  6457. /**
  6458. * get canvas layer
  6459. */
  6460. }, {
  6461. key: "getCanvasLayer",
  6462. value: function getCanvasLayer() {
  6463. if (!this.canvasLayer.canvas && !this.layer_) {
  6464. var extent = this.getMapExtent();
  6465. this.layer_ = new ol.layer.Image({
  6466. layerName: this.options.layerName,
  6467. minResolution: this.options.minResolution,
  6468. maxResolution: this.options.maxResolution,
  6469. zIndex: this.options.zIndex,
  6470. extent: extent,
  6471. source: new ol.source.ImageCanvas({
  6472. canvasFunction: this.canvasFunction.bind(this),
  6473. projection: this.$Map.getView().getProjection().getCode(), // 图层投影与Map保持一致
  6474. ratio: this.options.hasOwnProperty('ratio') ? this.options.ratio : 1
  6475. })
  6476. });
  6477. this.$Map.addLayer(this.layer_);
  6478. this.$Map.un('precompose', this.reRender, this);
  6479. this.$Map.on('precompose', this.reRender, this);
  6480. }
  6481. }
  6482. /**
  6483. * re render
  6484. */
  6485. }, {
  6486. key: "reRender",
  6487. value: function reRender() {
  6488. if (!this.layer_) return;
  6489. var extent = this.getMapExtent();
  6490. this.layer_.setExtent(extent);
  6491. }
  6492. /**
  6493. * canvas constructor
  6494. * @param extent
  6495. * @param resolution
  6496. * @param pixelRatio
  6497. * @param size
  6498. * @param projection
  6499. * @returns {*}
  6500. */
  6501. }, {
  6502. key: "canvasFunction",
  6503. value: function canvasFunction(extent, resolution, pixelRatio, size, projection) {
  6504. if (!this.canvasLayer.canvas) {
  6505. this.canvasLayer.canvas = createCanvas$1(size[0], size[1]);
  6506. } else {
  6507. this.canvasLayer.canvas.width = size[0];
  6508. this.canvasLayer.canvas.height = size[1];
  6509. }
  6510. this.render(this.canvasLayer.canvas);
  6511. return this.canvasLayer.canvas;
  6512. }
  6513. /**
  6514. * get map current extent
  6515. * @returns {Array}
  6516. */
  6517. }, {
  6518. key: "getMapExtent",
  6519. value: function getMapExtent() {
  6520. var size = this.$Map.getSize();
  6521. return this.$Map.getView().calculateExtent(size);
  6522. }
  6523. /**
  6524. * add layer to map
  6525. * @param map
  6526. */
  6527. }, {
  6528. key: "addTo",
  6529. value: function addTo(map) {
  6530. this.init(map, this.options);
  6531. }
  6532. /**
  6533. * remove layer
  6534. */
  6535. }, {
  6536. key: "removeLayer",
  6537. value: function removeLayer() {
  6538. if (!this.$Map) return;
  6539. this.unEvents();
  6540. this.$Map.un('precompose', this.reRender, this);
  6541. this.$Map.removeLayer(this.layer_);
  6542. delete this.$Map;
  6543. delete this.layer_;
  6544. delete this.canvasLayer.canvas;
  6545. }
  6546. }, {
  6547. key: "getContext",
  6548. value: function getContext() {
  6549. return this.canvasLayer.canvas.getContext(this.context);
  6550. }
  6551. /**
  6552. * handle click event
  6553. * @param event
  6554. */
  6555. }, {
  6556. key: "clickEvent",
  6557. value: function clickEvent(event) {
  6558. var pixel = event.pixel;
  6559. get(Layer.prototype.__proto__ || Object.getPrototypeOf(Layer.prototype), "clickEvent", this).call(this, {
  6560. x: pixel[0],
  6561. y: pixel[1]
  6562. }, event);
  6563. }
  6564. /**
  6565. * handle mousemove/pointermove event
  6566. * @param event
  6567. */
  6568. }, {
  6569. key: "mousemoveEvent",
  6570. value: function mousemoveEvent(event) {
  6571. var pixel = event.pixel;
  6572. get(Layer.prototype.__proto__ || Object.getPrototypeOf(Layer.prototype), "mousemoveEvent", this).call(this, {
  6573. x: pixel[0],
  6574. y: pixel[1]
  6575. }, event);
  6576. }
  6577. /**
  6578. * add animator event
  6579. */
  6580. }, {
  6581. key: "addAnimatorEvent",
  6582. value: function addAnimatorEvent() {
  6583. this.$Map.on('movestart', this.animatorMovestartEvent, this);
  6584. this.$Map.on('moveend', this.animatorMoveendEvent, this);
  6585. }
  6586. /**
  6587. * bind event
  6588. */
  6589. }, {
  6590. key: "onEvents",
  6591. value: function onEvents() {
  6592. var map = this.$Map;
  6593. this.unEvents();
  6594. if (this.options.methods) {
  6595. if (this.options.methods.click) {
  6596. map.on('click', this.clickEvent, this);
  6597. }
  6598. if (this.options.methods.mousemove) {
  6599. map.on('pointermove', this.mousemoveEvent, this);
  6600. }
  6601. }
  6602. }
  6603. /**
  6604. * unbind events
  6605. */
  6606. }, {
  6607. key: "unEvents",
  6608. value: function unEvents() {
  6609. var map = this.$Map;
  6610. if (this.options.methods) {
  6611. if (this.options.methods.click) {
  6612. map.un('click', this.clickEvent, this);
  6613. }
  6614. if (this.options.methods.pointermove) {
  6615. map.un('pointermove', this.mousemoveEvent, this);
  6616. }
  6617. }
  6618. }
  6619. /**
  6620. * set map cursor
  6621. * @param cursor
  6622. * @param feature
  6623. */
  6624. }, {
  6625. key: "setDefaultCursor",
  6626. value: function setDefaultCursor(cursor, feature) {
  6627. if (!this.$Map) return;
  6628. var element = this.$Map.getTargetElement();
  6629. if (feature) {
  6630. if (element.style.cursor !== cursor) {
  6631. this.previousCursor_ = element.style.cursor;
  6632. element.style.cursor = cursor;
  6633. }
  6634. } else if (this.previousCursor_ !== undefined) {
  6635. element.style.cursor = this.previousCursor_;
  6636. this.previousCursor_ = undefined;
  6637. }
  6638. }
  6639. /**
  6640. * 显示图层
  6641. */
  6642. }, {
  6643. key: "show",
  6644. value: function show() {
  6645. this.$Map.addLayer(this.layer_);
  6646. }
  6647. /**
  6648. * 隐藏图层
  6649. */
  6650. }, {
  6651. key: "hide",
  6652. value: function hide() {
  6653. this.$Map.removeLayer(this.layer_);
  6654. }
  6655. }]);
  6656. return Layer;
  6657. }(BaseLayer);
  6658. // https://github.com/SuperMap/iClient-JavaScript
  6659. /**
  6660. * @class MapVRenderer
  6661. * @classdesc 地图渲染类
  6662. * @category Visualization MapV
  6663. * @private
  6664. * @extends mapv.BaseLayer
  6665. * @param {L.Map} map - 待渲染的地图
  6666. * @param {L.Layer} layer - 待渲染的图层
  6667. * @param {DataSet} dataSet - 待渲染的数据集
  6668. * @param {Object} options - 渲染的参数
  6669. */
  6670. var MapVRenderer = function (_BaseLayer) {
  6671. inherits(MapVRenderer, _BaseLayer);
  6672. function MapVRenderer(map, layer, dataSet, options) {
  6673. classCallCheck(this, MapVRenderer);
  6674. var _this = possibleConstructorReturn(this, (MapVRenderer.__proto__ || Object.getPrototypeOf(MapVRenderer)).call(this, map, dataSet, options));
  6675. if (!BaseLayer) {
  6676. return possibleConstructorReturn(_this);
  6677. }
  6678. var self = _this;
  6679. options = options || {};
  6680. self.init(options);
  6681. self.argCheck(options);
  6682. _this.canvasLayer = layer;
  6683. _this.clickEvent = _this.clickEvent.bind(_this);
  6684. _this.mousemoveEvent = _this.mousemoveEvent.bind(_this);
  6685. _this._moveStartEvent = _this.moveStartEvent.bind(_this);
  6686. _this._moveEndEvent = _this.moveEndEvent.bind(_this);
  6687. _this._zoomStartEvent = _this.zoomStartEvent.bind(_this);
  6688. _this.bindEvent();
  6689. return _this;
  6690. }
  6691. /**
  6692. * @function MapVRenderer.prototype.clickEvent
  6693. * @description 点击事件
  6694. * @param {Object} e - 触发对象
  6695. */
  6696. createClass(MapVRenderer, [{
  6697. key: 'clickEvent',
  6698. value: function clickEvent(e) {
  6699. var offset = this.map.containerPointToLayerPoint([0, 0]);
  6700. // var devicePixelRatio = this.devicePixelRatio = this.canvasLayer.devicePixelRatio = window.devicePixelRatio;
  6701. var devicePixelRatio = 1;
  6702. this.devicePixelRatio = 1;
  6703. this.canvasLayer.devicePixelRatio = 1;
  6704. console.error("输出屏幕坐标:x="+(pixel.x - offset.x) / devicePixelRatio +";y="+(pixel.y - offset.y) / devicePixelRatio)
  6705. var pixel = e.layerPoint;
  6706. get(MapVRenderer.prototype.__proto__ || Object.getPrototypeOf(MapVRenderer.prototype), 'clickEvent', this).call(this, L.point((pixel.x - offset.x) / devicePixelRatio, (pixel.y - offset.y) / devicePixelRatio), e);
  6707. }
  6708. /**
  6709. * @function MapVRenderer.prototype.mousemoveEvent
  6710. * @description 鼠标移动事件
  6711. * @param {Object} e - 触发对象
  6712. */
  6713. }, {
  6714. key: 'mousemoveEvent',
  6715. value: function mousemoveEvent(e) {
  6716. var pixel = e.layerPoint;
  6717. get(MapVRenderer.prototype.__proto__ || Object.getPrototypeOf(MapVRenderer.prototype), 'mousemoveEvent', this).call(this, pixel, e);
  6718. }
  6719. /**
  6720. * @function MapVRenderer.prototype.bindEvent
  6721. * @description 绑定鼠标移动和鼠标点击事件
  6722. * @param {Object} e - 触发对象
  6723. */
  6724. }, {
  6725. key: 'bindEvent',
  6726. value: function bindEvent() {
  6727. var map = this.map;
  6728. if (this.options.methods) {
  6729. if (this.options.methods.click) {
  6730. map.on('click', this.clickEvent);
  6731. }
  6732. if (this.options.methods.mousemove) {
  6733. map.on('mousemove', this.mousemoveEvent);
  6734. }
  6735. }
  6736. this.map.on('movestart', this._moveStartEvent);
  6737. this.map.on('moveend', this._moveEndEvent);
  6738. this.map.on('zoomstart', this._zoomStartEvent);
  6739. }
  6740. /**
  6741. * @function MapVRenderer.prototype.destroy
  6742. * @description 释放资源
  6743. */
  6744. }, {
  6745. key: 'destroy',
  6746. value: function destroy() {
  6747. this.unbindEvent();
  6748. this.clearData();
  6749. this.animator && this.animator.stop();
  6750. this.animator = null;
  6751. this.canvasLayer = null;
  6752. }
  6753. /**
  6754. * @function MapVRenderer.prototype.unbindEvent
  6755. * @description 解绑鼠标移动和鼠标滑动触发的事件
  6756. * @param {Object} e - 触发对象
  6757. */
  6758. }, {
  6759. key: 'unbindEvent',
  6760. value: function unbindEvent() {
  6761. var map = this.map;
  6762. if (this.options.methods) {
  6763. if (this.options.methods.click) {
  6764. map.off('click', this.clickEvent);
  6765. }
  6766. if (this.options.methods.mousemove) {
  6767. map.off('mousemove', this.mousemoveEvent);
  6768. }
  6769. }
  6770. this.map.off('movestart', this._moveStartEvent);
  6771. this.map.off('moveend', this._moveEndEvent);
  6772. this.map.off('zoomstart', this._zoomStartEvent);
  6773. }
  6774. /**
  6775. * @function MapVRenderer.prototype.getContext
  6776. * @description 获取信息
  6777. */
  6778. }, {
  6779. key: 'getContext',
  6780. value: function getContext() {
  6781. return this.canvasLayer.getCanvas().getContext(this.context);
  6782. }
  6783. /**
  6784. * @function MapVRenderer.prototype.addData
  6785. * @description 添加数据
  6786. * @param {Object} data - 待添加的数据
  6787. * @param {Object} options - 待添加的数据信息
  6788. */
  6789. }, {
  6790. key: 'addData',
  6791. value: function addData(data, options) {
  6792. var _data = data;
  6793. if (data && data.get) {
  6794. _data = data.get();
  6795. }
  6796. this.dataSet.add(_data);
  6797. this.update({
  6798. options: options
  6799. });
  6800. }
  6801. /**
  6802. * @function MapVRenderer.prototype.update
  6803. * @description 更新图层
  6804. * @param {Object} opt - 待更新的数据
  6805. * @param {Object} opt.data - mapv数据集
  6806. * @param {Object} opt.options - mapv绘制参数
  6807. */
  6808. }, {
  6809. key: 'update',
  6810. value: function update(opt) {
  6811. var update = opt || {};
  6812. var _data = update.data;
  6813. if (_data && _data.get) {
  6814. _data = _data.get();
  6815. }
  6816. if (_data != undefined) {
  6817. this.dataSet.set(_data);
  6818. }
  6819. get(MapVRenderer.prototype.__proto__ || Object.getPrototypeOf(MapVRenderer.prototype), 'update', this).call(this, {
  6820. options: update.options
  6821. });
  6822. }
  6823. /**
  6824. * @function MapVRenderer.prototype.getData
  6825. * @description 获取数据
  6826. */
  6827. }, {
  6828. key: 'getData',
  6829. value: function getData() {
  6830. return this.dataSet;
  6831. }
  6832. /**
  6833. * @function MapVRenderer.prototype.removeData
  6834. * @description 删除符合过滤条件的数据
  6835. * @param {Function} filter - 过滤条件条件参数为数据项返回值为 true表示删除该元素否则表示不删除
  6836. */
  6837. }, {
  6838. key: 'removeData',
  6839. value: function removeData(_filter) {
  6840. if (!this.dataSet) {
  6841. return;
  6842. }
  6843. var newData = this.dataSet.get({
  6844. filter: function filter(data) {
  6845. return _filter != null && typeof _filter === "function" ? !_filter(data) : true;
  6846. }
  6847. });
  6848. this.dataSet.set(newData);
  6849. this.update({
  6850. options: null
  6851. });
  6852. }
  6853. /**
  6854. * @function MapVRenderer.prototype.clearData
  6855. * @description 清除数据
  6856. */
  6857. }, {
  6858. key: 'clearData',
  6859. value: function clearData() {
  6860. this.dataSet && this.dataSet.clear();
  6861. this.update({
  6862. options: null
  6863. });
  6864. }
  6865. }, {
  6866. key: '_canvasUpdate',
  6867. value: function _canvasUpdate(time) {
  6868. if (!this.canvasLayer) {
  6869. return;
  6870. }
  6871. var self = this;
  6872. var animationOptions = self.options.animation;
  6873. var context = this.getContext();
  6874. var map = this.map;
  6875. if (self.isEnabledTime()) {
  6876. if (time === undefined) {
  6877. this.clear(context);
  6878. return;
  6879. }
  6880. if (this.context === '2d') {
  6881. context.save();
  6882. context.globalCompositeOperation = 'destination-out';
  6883. context.fillStyle = 'rgba(0, 0, 0, .1)';
  6884. context.fillRect(0, 0, context.canvas.width, context.canvas.height);
  6885. context.restore();
  6886. }
  6887. } else {
  6888. this.clear(context);
  6889. }
  6890. if (this.context === '2d') {
  6891. for (var key in self.options) {
  6892. context[key] = self.options[key];
  6893. }
  6894. } else {
  6895. context.clear(context.COLOR_BUFFER_BIT);
  6896. }
  6897. if (self.options.minZoom && map.getZoom() < self.options.minZoom || self.options.maxZoom && map.getZoom() > self.options.maxZoom) {
  6898. return;
  6899. }
  6900. var bounds = map.getBounds();
  6901. //获取当前像素下的地理范围
  6902. var dw = bounds.getEast() - bounds.getWest();
  6903. var dh = bounds.getNorth() - bounds.getSouth();
  6904. var mapCanvas = map.getSize();
  6905. var resolutionX = dw / mapCanvas.x,
  6906. resolutionY = dh / mapCanvas.y;
  6907. //var centerPx = map.latLngToLayerPoint(map.getCenter());
  6908. //获取屏幕左上角的地理坐标坐标
  6909. //左上角屏幕坐标为0,0
  6910. var topLeft = this.canvasLayer.getTopLeft();
  6911. var topLeftPX = map.latLngToContainerPoint(topLeft);
  6912. // 获取精确的像素坐标. https://github.com/SuperMap/iClient-JavaScript/blob/eacc26952b8915bba0122db751d766056c5fb24d/src/leaflet/core/Base.js
  6913. // var topLeftPX = map.latLngToAccurateContainerPoint(topLeft);
  6914. // var lopLeft = map.containerPointToLatLng([0, 0]);
  6915. var dataGetOptions = {
  6916. transferCoordinate: function transferCoordinate(coordinate) {
  6917. var offset;
  6918. if (self.context === '2d') {
  6919. offset = map.latLngToContainerPoint(L.latLng(coordinate[1], coordinate[0]));
  6920. // offset = map.latLngToAccurateContainerPoint(L.latLng(coordinate[1], coordinate[0]));
  6921. } else {
  6922. offset = {
  6923. 'x': (coordinate[0] - topLeft.lng) / resolutionX,
  6924. 'y': (topLeft.lat - coordinate[1]) / resolutionY
  6925. };
  6926. }
  6927. var pixel = {
  6928. x: offset.x - topLeftPX.x,
  6929. y: offset.y - topLeftPX.y
  6930. };
  6931. return [pixel.x, pixel.y];
  6932. }
  6933. };
  6934. if (time !== undefined) {
  6935. dataGetOptions.filter = function (item) {
  6936. var trails = animationOptions.trails || 10;
  6937. return time && item.time > time - trails && item.time < time;
  6938. };
  6939. }
  6940. var data = self.dataSet.get(dataGetOptions);
  6941. this.processData(data);
  6942. self.options._size = self.options.size;
  6943. var worldPoint = map.latLngToContainerPoint(L.latLng(0, 0));
  6944. var pixel = {
  6945. x: worldPoint.x - topLeftPX.x,
  6946. y: worldPoint.y - topLeftPX.y
  6947. };
  6948. this.drawContext(context, data, self.options, pixel);
  6949. self.options.updateCallback && self.options.updateCallback(time);
  6950. }
  6951. }, {
  6952. key: 'init',
  6953. value: function init(options) {
  6954. var self = this;
  6955. self.options = options;
  6956. this.initDataRange(options);
  6957. this.context = self.options.context || '2d';
  6958. if (self.options.zIndex) {
  6959. this.canvasLayer && this.canvasLayer.setZIndex(self.options.zIndex);
  6960. }
  6961. this.initAnimator();
  6962. }
  6963. }, {
  6964. key: 'addAnimatorEvent',
  6965. value: function addAnimatorEvent() {}
  6966. /**
  6967. * @function MapVRenderer.prototype.moveStartEvent
  6968. * @description 开始移动事件
  6969. */
  6970. }, {
  6971. key: 'moveStartEvent',
  6972. value: function moveStartEvent() {
  6973. var animationOptions = this.options.animation;
  6974. if (this.isEnabledTime() && this.animator) {
  6975. this.steps.step = animationOptions.stepsRange.start;
  6976. this._hide();
  6977. }
  6978. }
  6979. /**
  6980. * @function MapVRenderer.prototype.moveEndEvent
  6981. * @description 结束移动事件
  6982. */
  6983. }, {
  6984. key: 'moveEndEvent',
  6985. value: function moveEndEvent() {
  6986. this.canvasLayer.draw();
  6987. this._show();
  6988. }
  6989. /**
  6990. * @function MapVRenderer.prototype.zoomStartEvent
  6991. * @description 隐藏渲染样式
  6992. */
  6993. }, {
  6994. key: 'zoomStartEvent',
  6995. value: function zoomStartEvent() {
  6996. this._hide();
  6997. }
  6998. /**
  6999. * @function MapVRenderer.prototype.clear
  7000. * @description 清除信息
  7001. * @param {string} context - 指定要清除的信息
  7002. */
  7003. }, {
  7004. key: 'clear',
  7005. value: function clear(context) {
  7006. context && context.clearRect && context.clearRect(0, 0, context.canvas.width, context.canvas.height);
  7007. }
  7008. }, {
  7009. key: '_hide',
  7010. value: function _hide() {
  7011. this.canvasLayer.canvas.style.display = 'none';
  7012. }
  7013. }, {
  7014. key: '_show',
  7015. value: function _show() {
  7016. this.canvasLayer.canvas.style.display = 'block';
  7017. }
  7018. /**
  7019. * @function MapVRenderer.prototype.draw
  7020. * @description 绘制渲染
  7021. */
  7022. }, {
  7023. key: 'draw',
  7024. value: function draw() {
  7025. this.canvasLayer.draw();
  7026. }
  7027. }]);
  7028. return MapVRenderer;
  7029. }(BaseLayer);
  7030. var mapVLayer;
  7031. if (typeof L !== 'undefined') {
  7032. /**
  7033. * @class mapVLayer
  7034. * @classdesc MapV 图层
  7035. * @category Visualization MapV
  7036. * @extends {L.Layer}
  7037. * @param {mapv.DataSet} dataSet - MapV 图层数据集
  7038. * @param {Object} mapVOptions - MapV 图层参数
  7039. * @param {Object} options - 参数
  7040. * @param {string} [options.attributionPrefix] - 版权信息前缀
  7041. * @param {string} [options.attribution='© 2018 百度 MapV'] - 版权信息
  7042. * @fires mapVLayer#loaded
  7043. */
  7044. var MapVLayer = L.Layer.extend({
  7045. options: {
  7046. attributionPrefix: null,
  7047. attribution: ''
  7048. },
  7049. initialize: function initialize(dataSet, mapVOptions, options) {
  7050. options = options || {};
  7051. this.dataSet = dataSet || {};
  7052. this.mapVOptions = mapVOptions || {};
  7053. this.render = this.render.bind(this);
  7054. L.Util.setOptions(this, options);
  7055. if (this.options.attributionPrefix) {
  7056. this.options.attribution = this.options.attributionPrefix + this.options.attribution;
  7057. }
  7058. this.canvas = this._createCanvas();
  7059. L.stamp(this);
  7060. },
  7061. /**
  7062. * @private
  7063. * @function mapVLayer.prototype.onAdd
  7064. * @description 添加地图图层
  7065. * @param {L.Map} map - 要添加的地图
  7066. */
  7067. onAdd: function onAdd(map) {
  7068. this._map = map;
  7069. var overlayPane = this.getPane();
  7070. var container = this.container = L.DomUtil.create("div", "leaflet-layer leaflet-zoom-animated", overlayPane);
  7071. container.appendChild(this.canvas);
  7072. var size = map.getSize();
  7073. container.style.width = size.x + "px";
  7074. container.style.height = size.y + "px";
  7075. this.renderer = new MapVRenderer(map, this, this.dataSet, this.mapVOptions);
  7076. this.draw();
  7077. /**
  7078. * @event mapVLayer#loaded
  7079. * @description 图层添加完成之后触发
  7080. */
  7081. this.fire("loaded");
  7082. },
  7083. // _hide: function () {
  7084. // this.canvas.style.display = 'none';
  7085. // },
  7086. // _show: function () {
  7087. // this.canvas.style.display = 'block';
  7088. // },
  7089. /**
  7090. * @private
  7091. * @function mapVLayer.prototype.onRemove
  7092. * @description 删除地图图层
  7093. */
  7094. onRemove: function onRemove() {
  7095. L.DomUtil.remove(this.container);
  7096. this.renderer.destroy();
  7097. },
  7098. /**
  7099. * @function mapVLayer.prototype.addData
  7100. * @description 追加数据
  7101. * @param {Object} data - 要追加的数据
  7102. * @param {Object} options - 要追加的值
  7103. */
  7104. addData: function addData(data, options) {
  7105. this.renderer.addData(data, options);
  7106. },
  7107. /**
  7108. * @function mapVLayer.prototype.update
  7109. * @description 更新图层
  7110. * @param {Object} opt - 待更新的数据
  7111. * @param {Object} data - mapv 数据集
  7112. * @param {Object} options - mapv 绘制参数
  7113. */
  7114. update: function update(opt) {
  7115. this.renderer.update(opt);
  7116. },
  7117. /**
  7118. * @function mapVLayer.prototype.getData
  7119. * @description 获取数据
  7120. * @returns {mapv.DataSet} mapv 数据集
  7121. */
  7122. getData: function getData() {
  7123. if (this.renderer) {
  7124. this.dataSet = this.renderer.getData();
  7125. }
  7126. return this.dataSet;
  7127. },
  7128. /**
  7129. * @function mapVLayer.prototype.removeData
  7130. * @description 删除符合过滤条件的数据
  7131. * @param {Function} filter - 过滤条件条件参数为数据项返回值为 true表示删除该元素否则表示不删除
  7132. * @example
  7133. * filter=function(data){
  7134. * if(data.id=="1"){
  7135. * return true
  7136. * }
  7137. * return false;
  7138. * }
  7139. */
  7140. removeData: function removeData(filter) {
  7141. this.renderer && this.renderer.removeData(filter);
  7142. },
  7143. /**
  7144. * @function mapVLayer.prototype.clearData
  7145. * @description 清除数据
  7146. */
  7147. clearData: function clearData() {
  7148. this.renderer.clearData();
  7149. },
  7150. /**
  7151. * @function mapVLayer.prototype.draw
  7152. * @description 绘制图层
  7153. */
  7154. draw: function draw() {
  7155. return this._reset();
  7156. },
  7157. /**
  7158. * @function mapVLayer.prototype.setZIndex
  7159. * @description 设置 canvas 层级
  7160. * @param {number} zIndex - canvas 层级
  7161. */
  7162. setZIndex: function setZIndex(zIndex) {
  7163. this.canvas.style.zIndex = zIndex;
  7164. },
  7165. /**
  7166. * @function mapVLayer.prototype.render
  7167. * @description 渲染
  7168. */
  7169. render: function render() {
  7170. this.renderer._canvasUpdate();
  7171. },
  7172. /**
  7173. * @function mapVLayer.prototype.getCanvas
  7174. * @description 获取 canvas
  7175. * @returns {HTMLElement} 返回 mapV 图层包含的 canvas 对象
  7176. */
  7177. getCanvas: function getCanvas() {
  7178. return this.canvas;
  7179. },
  7180. /**
  7181. * @function mapVLayer.prototype.getContainer
  7182. * @description 获取容器
  7183. * @returns {HTMLElement} 返回包含 mapV 图层的 dom 对象
  7184. */
  7185. getContainer: function getContainer() {
  7186. return this.container;
  7187. },
  7188. /**
  7189. * @function mapVLayer.prototype.getTopLeft
  7190. * @description 获取左上角坐标
  7191. * @returns {L.Bounds} 返回左上角坐标
  7192. */
  7193. getTopLeft: function getTopLeft() {
  7194. var map = this._map;
  7195. var topLeft;
  7196. if (map) {
  7197. var bounds = map.getBounds();
  7198. topLeft = bounds.getNorthWest();
  7199. }
  7200. return topLeft;
  7201. },
  7202. _createCanvas: function _createCanvas() {
  7203. var canvas = document.createElement('canvas');
  7204. canvas.style.position = 'absolute';
  7205. canvas.style.top = 0 + "px";
  7206. canvas.style.left = 0 + "px";
  7207. canvas.style.pointerEvents = "none";
  7208. canvas.style.zIndex = this.options.zIndex || 600;
  7209. var global$2 = typeof window === 'undefined' ? {} : window;
  7210. var devicePixelRatio = this.devicePixelRatio = global$2.devicePixelRatio;
  7211. if (!this.mapVOptions.context || this.mapVOptions.context === '2d') {
  7212. canvas.getContext('2d').scale(devicePixelRatio, devicePixelRatio);
  7213. }
  7214. return canvas;
  7215. },
  7216. _resize: function _resize() {
  7217. var canvas = this.canvas;
  7218. if (!canvas) {
  7219. return;
  7220. }
  7221. var map = this._map;
  7222. var size = map.getSize();
  7223. canvas.width = size.x;
  7224. canvas.height = size.y;
  7225. canvas.style.width = size.x + 'px';
  7226. canvas.style.height = size.y + 'px';
  7227. var bounds = map.getBounds();
  7228. var topLeft = map.latLngToLayerPoint(bounds.getNorthWest());
  7229. L.DomUtil.setPosition(canvas, topLeft);
  7230. },
  7231. _reset: function _reset() {
  7232. this._resize();
  7233. this._render();
  7234. },
  7235. redraw: function redraw() {
  7236. this._resize();
  7237. this._render();
  7238. },
  7239. _render: function _render() {
  7240. this.render();
  7241. }
  7242. });
  7243. mapVLayer = function mapVLayer(dataSet, mapVOptions, options) {
  7244. return new MapVLayer(dataSet, mapVOptions, options);
  7245. };
  7246. }
  7247. var mapVLayer$1 = mapVLayer;
  7248. var MapVRenderer$1 = function (_BaseLayer) {
  7249. inherits(MapVRenderer, _BaseLayer);
  7250. /**
  7251. * Creates an instance of MapVRenderer.
  7252. * @param {*} viewer cesium viewer
  7253. * @param {*} dataset mapv dataset
  7254. * @param {*} option mapvOptions
  7255. * @param {*} mapVLayer
  7256. * @memberof MapVRenderer
  7257. */
  7258. function MapVRenderer(viewer, dataset, option, mapVLayer) {
  7259. classCallCheck(this, MapVRenderer);
  7260. var _this = possibleConstructorReturn(this, (MapVRenderer.__proto__ || Object.getPrototypeOf(MapVRenderer)).call(this, viewer, dataset, option));
  7261. if (!BaseLayer) {
  7262. return possibleConstructorReturn(_this);
  7263. }
  7264. _this.map = viewer, _this.scene = viewer.scene, _this.dataSet = dataset;
  7265. option = option || {}, _this.init(option), _this.argCheck(option), _this.initDevicePixelRatio(), _this.canvasLayer = mapVLayer, _this.stopAniamation = !1, _this.animation = option.animation, _this.clickEvent = _this.clickEvent.bind(_this), _this.mousemoveEvent = _this.mousemoveEvent.bind(_this), _this.bindEvent();
  7266. return _this;
  7267. }
  7268. createClass(MapVRenderer, [{
  7269. key: "initDevicePixelRatio",
  7270. value: function initDevicePixelRatio() {
  7271. this.devicePixelRatio = 1 || 1;
  7272. }
  7273. }, {
  7274. key: "clickEvent",
  7275. value: function clickEvent(t) {
  7276. var e = t.point;
  7277. alert(e);
  7278. get(MapVRenderer.prototype.__proto__ || Object.getPrototypeOf(MapVRenderer.prototype), "clickEvent", this).call(this, e, t);
  7279. }
  7280. }, {
  7281. key: "mousemoveEvent",
  7282. value: function mousemoveEvent(t) {
  7283. var e = t.point;
  7284. get(MapVRenderer.prototype.__proto__ || Object.getPrototypeOf(MapVRenderer.prototype), "mousemoveEvent", this).call(this, e, t);
  7285. }
  7286. }, {
  7287. key: "addAnimatorEvent",
  7288. value: function addAnimatorEvent() {}
  7289. }, {
  7290. key: "animatorMovestartEvent",
  7291. value: function animatorMovestartEvent() {
  7292. var t = this.options.animation;
  7293. this.isEnabledTime() && this.animator && (this.steps.step = t.stepsRange.start);
  7294. }
  7295. }, {
  7296. key: "animatorMoveendEvent",
  7297. value: function animatorMoveendEvent() {
  7298. this.isEnabledTime() && this.animator;
  7299. }
  7300. }, {
  7301. key: "bindEvent",
  7302. value: function bindEvent() {
  7303. this.map;
  7304. this.options.methods && (this.options.methods.click, this.options.methods.mousemove);
  7305. }
  7306. }, {
  7307. key: "unbindEvent",
  7308. value: function unbindEvent() {
  7309. var t = this.map;
  7310. this.options.methods && (this.options.methods.click && t.off("click", this.clickEvent), this.options.methods.mousemove && t.off("mousemove", this.mousemoveEvent));
  7311. }
  7312. }, {
  7313. key: "getContext",
  7314. value: function getContext() {
  7315. return this.canvasLayer.canvas.getContext(this.context);
  7316. }
  7317. }, {
  7318. key: "init",
  7319. value: function init(t) {
  7320. this.options = t, this.initDataRange(t), this.context = this.options.context || "2d", this.options.zIndex && this.canvasLayer && this.canvasLayer.setZIndex(this.options.zIndex), this.initAnimator();
  7321. }
  7322. }, {
  7323. key: "_canvasUpdate",
  7324. value: function _canvasUpdate(t) {
  7325. this.map;
  7326. var e = this.scene;
  7327. if (this.canvasLayer && !this.stopAniamation) {
  7328. var i = this.options.animation,
  7329. n = this.getContext();
  7330. if (this.isEnabledTime()) {
  7331. if (void 0 === t) return void this.clear(n);
  7332. "2d" === this.context && (n.save(), n.globalCompositeOperation = "destination-out", n.fillStyle = "rgba(0, 0, 0, .1)", n.fillRect(0, 0, n.canvas.width, n.canvas.height), n.restore());
  7333. } else this.clear(n);
  7334. if ("2d" === this.context) for (var o in this.options) {
  7335. n[o] = this.options[o];
  7336. } else n.clear(n.COLOR_BUFFER_BIT);
  7337. var a = {
  7338. transferCoordinate: function transferCoordinate(t) {
  7339. var i = Cesium.Cartesian3.fromDegrees(t[0], t[1]),
  7340. n = Cesium.SceneTransforms.wgs84ToWindowCoordinates(e, i);
  7341. return void 0 == n ? [-1, -1] : [n.x, n.y];
  7342. }
  7343. };
  7344. void 0 !== t && (a.filter = function (e) {
  7345. var n = i.trails || 10;
  7346. return !!(t && e.time > t - n && e.time < t);
  7347. });
  7348. var c = this.dataSet.get(a);
  7349. this.processData(c), "m" == this.options.unit && this.options.size, this.options._size = this.options.size;
  7350. var h = Cesium.SceneTransforms.wgs84ToWindowCoordinates(e, Cesium.Cartesian3.fromDegrees(0, 0));
  7351. this.drawContext(n, new DataSet(c), this.options, h), this.options.updateCallback && this.options.updateCallback(t);
  7352. }
  7353. }
  7354. }, {
  7355. key: "updateData",
  7356. value: function updateData(t, e) {
  7357. var i = t;
  7358. i && i.get && (i = i.get()), void 0 != i && this.dataSet.set(i), get(MapVRenderer.prototype.__proto__ || Object.getPrototypeOf(MapVRenderer.prototype), "update", this).call(this, {
  7359. options: e
  7360. });
  7361. }
  7362. }, {
  7363. key: "addData",
  7364. value: function addData(t, e) {
  7365. var i = t;
  7366. t && t.get && (i = t.get()), this.dataSet.add(i), this.update({
  7367. options: e
  7368. });
  7369. }
  7370. }, {
  7371. key: "getData",
  7372. value: function getData() {
  7373. return this.dataSet;
  7374. }
  7375. }, {
  7376. key: "removeData",
  7377. value: function removeData(t) {
  7378. if (this.dataSet) {
  7379. var e = this.dataSet.get({
  7380. filter: function filter(e) {
  7381. return null == t || "function" != typeof t || !t(e);
  7382. }
  7383. });
  7384. this.dataSet.set(e), this.update({
  7385. options: null
  7386. });
  7387. }
  7388. }
  7389. }, {
  7390. key: "clearData",
  7391. value: function clearData() {
  7392. this.dataSet && this.dataSet.clear(), this.update({
  7393. options: null
  7394. });
  7395. }
  7396. }, {
  7397. key: "draw",
  7398. value: function draw() {
  7399. this.canvasLayer.draw();
  7400. }
  7401. }, {
  7402. key: "clear",
  7403. value: function clear(t) {
  7404. t && t.clearRect && t.clearRect(0, 0, t.canvas.width, t.canvas.height);
  7405. }
  7406. }]);
  7407. return MapVRenderer;
  7408. }(BaseLayer);
  7409. var mapVLayer$2;
  7410. if (typeof Cesium !== 'undefined') {
  7411. var defIndex = 0;
  7412. var r = Cesium;
  7413. var MapVLayer$1 = function () {
  7414. /**
  7415. *Creates an instance of MapVLayer.
  7416. * @param {*} viewer
  7417. * @param {*} dataset
  7418. * @param {*} options
  7419. * @param {*} container default viewer.container
  7420. * @memberof MapVLayer
  7421. */
  7422. function MapVLayer(viewer, dataset, options, container) {
  7423. classCallCheck(this, MapVLayer);
  7424. this.map = viewer, this.scene = viewer.scene, this.mapvBaseLayer = new MapVRenderer$1(viewer, dataset, options, this), this.mapVOptions = options, this.initDevicePixelRatio(), this.canvas = this._createCanvas(), this.render = this.render.bind(this);
  7425. if (container) {
  7426. this.container = container;
  7427. } else {
  7428. var inner = viewer.container.querySelector('.cesium-viewer-cesiumWidgetContainer');
  7429. this.container = inner ? inner : viewer.container;
  7430. }
  7431. this.addInnerContainer();
  7432. // void 0 != container ? (this.container = container,
  7433. // container.appendChild(this.canvas)) : (this.container = viewer.container,
  7434. // this.addInnerContainer()),
  7435. this.bindEvent();
  7436. this._reset();
  7437. }
  7438. createClass(MapVLayer, [{
  7439. key: 'initDevicePixelRatio',
  7440. value: function initDevicePixelRatio() {
  7441. this.devicePixelRatio = 1 || 1;
  7442. }
  7443. }, {
  7444. key: 'addInnerContainer',
  7445. value: function addInnerContainer() {
  7446. this.container.appendChild(this.canvas);
  7447. }
  7448. }, {
  7449. key: 'bindEvent',
  7450. value: function bindEvent() {
  7451. var that = this;
  7452. this.innerMoveStart = this.moveStartEvent.bind(this);
  7453. this.innerMoveEnd = this.moveEndEvent.bind(this);
  7454. this.scene.camera.moveStart.addEventListener(this.innerMoveStart, this);
  7455. this.scene.camera.moveEnd.addEventListener(this.innerMoveEnd, this);
  7456. var t = new Cesium.ScreenSpaceEventHandler(this.scene.canvas);
  7457. t.setInputAction(function (t) {
  7458. that.innerMoveEnd();
  7459. }, Cesium.ScreenSpaceEventType.LEFT_UP);
  7460. t.setInputAction(function (t) {
  7461. that.innerMoveEnd();
  7462. }, Cesium.ScreenSpaceEventType.MIDDLE_UP);
  7463. this.handler = t;
  7464. }
  7465. }, {
  7466. key: 'unbindEvent',
  7467. value: function unbindEvent() {
  7468. this.scene.camera.moveStart.removeEventListener(this.innerMoveStart, this);
  7469. this.scene.camera.moveEnd.removeEventListener(this.innerMoveEnd, this);
  7470. this.scene.postRender.removeEventListener(this._reset, this);
  7471. this.handler && (this.handler.destroy(), this.handler = null);
  7472. }
  7473. }, {
  7474. key: 'moveStartEvent',
  7475. value: function moveStartEvent() {
  7476. if (this.mapvBaseLayer) {
  7477. this.mapvBaseLayer.animatorMovestartEvent();
  7478. this.scene.postRender.addEventListener(this._reset, this);
  7479. }
  7480. }
  7481. }, {
  7482. key: 'moveEndEvent',
  7483. value: function moveEndEvent() {
  7484. if (this.mapvBaseLayer) {
  7485. this.scene.postRender.removeEventListener(this._reset, this), this.mapvBaseLayer.animatorMoveendEvent();
  7486. this._reset();
  7487. }
  7488. }
  7489. }, {
  7490. key: 'zoomStartEvent',
  7491. value: function zoomStartEvent() {
  7492. this._unvisiable();
  7493. }
  7494. }, {
  7495. key: 'zoomEndEvent',
  7496. value: function zoomEndEvent() {
  7497. this._unvisiable();
  7498. }
  7499. }, {
  7500. key: 'addData',
  7501. value: function addData(t, e) {
  7502. void 0 != this.mapvBaseLayer && this.mapvBaseLayer.addData(t, e);
  7503. }
  7504. }, {
  7505. key: 'updateData',
  7506. value: function updateData(t, e) {
  7507. void 0 != this.mapvBaseLayer && this.mapvBaseLayer.updateData(t, e);
  7508. }
  7509. }, {
  7510. key: 'getData',
  7511. value: function getData() {
  7512. return this.mapvBaseLayer && (this.dataSet = this.mapvBaseLayer.getData()), this.dataSet;
  7513. }
  7514. }, {
  7515. key: 'removeData',
  7516. value: function removeData(t) {
  7517. void 0 != this.mapvBaseLayer && this.mapvBaseLayer && this.mapvBaseLayer.removeData(t);
  7518. }
  7519. }, {
  7520. key: 'removeAllData',
  7521. value: function removeAllData() {
  7522. void 0 != this.mapvBaseLayer && this.mapvBaseLayer.clearData();
  7523. }
  7524. }, {
  7525. key: '_visiable',
  7526. value: function _visiable() {
  7527. return this.canvas.style.display = "block", this;
  7528. }
  7529. }, {
  7530. key: '_unvisiable',
  7531. value: function _unvisiable() {
  7532. return this.canvas.style.display = "none", this;
  7533. }
  7534. }, {
  7535. key: '_createCanvas',
  7536. value: function _createCanvas() {
  7537. var t = document.createElement("canvas");
  7538. t.id = this.mapVOptions.layerid || "mapv" + defIndex++, t.style.position = "absolute", t.style.top = "0px", t.style.left = "0px", t.style.pointerEvents = "none", t.style.zIndex = this.mapVOptions.zIndex || 0, t.width = parseInt(this.map.canvas.width), t.height = parseInt(this.map.canvas.height), t.style.width = this.map.canvas.style.width, t.style.height = this.map.canvas.style.height;
  7539. var e = this.devicePixelRatio;
  7540. return "2d" == this.mapVOptions.context && t.getContext(this.mapVOptions.context).scale(e, e), t;
  7541. }
  7542. }, {
  7543. key: '_reset',
  7544. value: function _reset() {
  7545. this.resizeCanvas();
  7546. this.fixPosition();
  7547. this.onResize();
  7548. this.render();
  7549. }
  7550. }, {
  7551. key: 'draw',
  7552. value: function draw() {
  7553. this._reset();
  7554. }
  7555. }, {
  7556. key: 'show',
  7557. value: function show() {
  7558. this._visiable();
  7559. }
  7560. }, {
  7561. key: 'hide',
  7562. value: function hide() {
  7563. this._unvisiable();
  7564. }
  7565. }, {
  7566. key: 'destroy',
  7567. value: function destroy() {
  7568. this.remove();
  7569. }
  7570. }, {
  7571. key: 'remove',
  7572. value: function remove() {
  7573. void 0 != this.mapvBaseLayer && (this.removeAllData(), this.mapvBaseLayer.clear(this.mapvBaseLayer.getContext()), this.mapvBaseLayer = void 0, this.canvas.parentElement.removeChild(this.canvas));
  7574. }
  7575. }, {
  7576. key: 'update',
  7577. value: function update(t) {
  7578. void 0 != t && this.updateData(t.data, t.options);
  7579. }
  7580. }, {
  7581. key: 'resizeCanvas',
  7582. value: function resizeCanvas() {
  7583. if (void 0 != this.canvas && null != this.canvas) {
  7584. var t = this.canvas;
  7585. t.style.position = "absolute", t.style.top = "0px", t.style.left = "0px", t.width = parseInt(this.map.canvas.width), t.height = parseInt(this.map.canvas.height), t.style.width = this.map.canvas.style.width, t.style.height = this.map.canvas.style.height;
  7586. }
  7587. }
  7588. }, {
  7589. key: 'fixPosition',
  7590. value: function fixPosition() {}
  7591. }, {
  7592. key: 'onResize',
  7593. value: function onResize() {}
  7594. }, {
  7595. key: 'render',
  7596. value: function render() {
  7597. void 0 != this.mapvBaseLayer && this.mapvBaseLayer._canvasUpdate();
  7598. }
  7599. }]);
  7600. return MapVLayer;
  7601. }();
  7602. mapVLayer$2 = function mapVLayer(viewer, dataSet, mapVOptions, container) {
  7603. return new MapVLayer$1(viewer, dataSet, mapVOptions, container);
  7604. };
  7605. }
  7606. var mapVLayer$3 = mapVLayer$2;
  7607. /**
  7608. * @author kyle / http://nikai.us/
  7609. */
  7610. var geojson = {
  7611. getDataSet: function getDataSet(geoJson) {
  7612. var data = [];
  7613. var features = geoJson.features;
  7614. if (features) {
  7615. for (var i = 0; i < features.length; i++) {
  7616. var feature = features[i];
  7617. var geometry = feature.geometry;
  7618. var properties = feature.properties;
  7619. var item = {};
  7620. for (var key in properties) {
  7621. item[key] = properties[key];
  7622. }
  7623. item.geometry = geometry;
  7624. data.push(item);
  7625. }
  7626. }
  7627. return new DataSet(data);
  7628. }
  7629. };
  7630. /**
  7631. * @author kyle / http://nikai.us/
  7632. */
  7633. var csv = {
  7634. CSVToArray: function CSVToArray(strData, strDelimiter) {
  7635. // Check to see if the delimiter is defined. If not,
  7636. // then default to comma.
  7637. strDelimiter = strDelimiter || ",";
  7638. // Create a regular expression to parse the CSV values.
  7639. var objPattern = new RegExp(
  7640. // Delimiters.
  7641. "(\\" + strDelimiter + "|\\r?\\n|\\r|^)" +
  7642. // Quoted fields.
  7643. "(?:\"([^\"]*(?:\"\"[^\"]*)*)\"|" +
  7644. // Standard fields.
  7645. "([^\"\\" + strDelimiter + "\\r\\n]*))", "gi");
  7646. // Create an array to hold our data. Give the array
  7647. // a default empty first row.
  7648. var arrData = [[]];
  7649. // Create an array to hold our individual pattern
  7650. // matching groups.
  7651. var arrMatches = null;
  7652. // Keep looping over the regular expression matches
  7653. // until we can no longer find a match.
  7654. while (arrMatches = objPattern.exec(strData)) {
  7655. // Get the delimiter that was found.
  7656. var strMatchedDelimiter = arrMatches[1];
  7657. // Check to see if the given delimiter has a length
  7658. // (is not the start of string) and if it matches
  7659. // field delimiter. If id does not, then we know
  7660. // that this delimiter is a row delimiter.
  7661. if (strMatchedDelimiter.length && strMatchedDelimiter !== strDelimiter) {
  7662. // Since we have reached a new row of data,
  7663. // add an empty row to our data array.
  7664. arrData.push([]);
  7665. }
  7666. var strMatchedValue;
  7667. // Now that we have our delimiter out of the way,
  7668. // let's check to see which kind of value we
  7669. // captured (quoted or unquoted).
  7670. if (arrMatches[2]) {
  7671. // We found a quoted value. When we capture
  7672. // this value, unescape any double quotes.
  7673. strMatchedValue = arrMatches[2].replace(new RegExp("\"\"", "g"), "\"");
  7674. } else {
  7675. // We found a non-quoted value.
  7676. strMatchedValue = arrMatches[3];
  7677. }
  7678. // Now that we have our value string, let's add
  7679. // it to the data array.
  7680. arrData[arrData.length - 1].push(strMatchedValue);
  7681. }
  7682. // Return the parsed data.
  7683. return arrData;
  7684. },
  7685. getDataSet: function getDataSet(csvStr, split) {
  7686. var arr = this.CSVToArray(csvStr, split || ',');
  7687. var data = [];
  7688. var header = arr[0];
  7689. for (var i = 1; i < arr.length - 1; i++) {
  7690. var line = arr[i];
  7691. var item = {};
  7692. for (var j = 0; j < line.length; j++) {
  7693. var value = line[j];
  7694. if (header[j] == 'geometry') {
  7695. value = JSON.parse(value);
  7696. }
  7697. item[header[j]] = value;
  7698. }
  7699. data.push(item);
  7700. }
  7701. return new DataSet(data);
  7702. }
  7703. };
  7704. exports.version = version;
  7705. exports.canvasClear = clear;
  7706. exports.canvasResolutionScale = resolutionScale$1;
  7707. exports.canvasDrawSimple = drawSimple;
  7708. exports.canvasDrawHeatmap = drawHeatmap;
  7709. exports.canvasDrawGrid = drawGrid;
  7710. exports.canvasDrawHoneycomb = drawHoneycomb;
  7711. exports.webglDrawSimple = webglDrawSimple;
  7712. exports.webglDrawPoint = point;
  7713. exports.webglDrawLine = line;
  7714. exports.webglDrawPolygon = polygon;
  7715. exports.utilCityCenter = cityCenter;
  7716. exports.utilCurve = curve;
  7717. exports.utilForceEdgeBundling = ForceEdgeBundling;
  7718. exports.utilDataRangeIntensity = Intensity;
  7719. exports.utilDataRangeCategory = Category;
  7720. exports.utilDataRangeChoropleth = Choropleth;
  7721. exports.Map = MapHelper;
  7722. exports.baiduMapCanvasLayer = CanvasLayer;
  7723. exports.baiduMapAnimationLayer = AnimationLayer;
  7724. exports.baiduMapLayer = Layer;
  7725. exports.googleMapCanvasLayer = CanvasLayer$2;
  7726. exports.googleMapLayer = Layer$2;
  7727. exports.MaptalksLayer = Layer$5;
  7728. exports.AMapLayer = Layer$6;
  7729. exports.OpenlayersLayer = Layer$8;
  7730. exports.leafletMapLayer = mapVLayer$1;
  7731. exports.cesiumMapLayer = mapVLayer$3;
  7732. exports.DataSet = DataSet;
  7733. exports.geojson = geojson;
  7734. exports.csv = csv;
  7735. Object.defineProperty(exports, '__esModule', { value: true });
  7736. })));