airPlume.js 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366
  1. /**
  2. * 风羽功能
  3. * Created by Administrator on 2017/11/7.
  4. */
  5. define([], function () {
  6. var airPlume = {
  7. id: 'air',
  8. title: '风场', //风羽功能标题
  9. isInit: false,
  10. level: null, //当前要显示的风羽层级
  11. layer: null, //风羽所在地图图层id
  12. slat: null, //风羽图开始lat
  13. slng: null, //风羽图开始lng
  14. elat: null, //风羽图结束lat
  15. elng: null, //风羽图结束lng
  16. delta: null, //风羽图每个数据地理间隔
  17. rowNum: null, //lng跨度
  18. colNum: null, //lat跨度
  19. ws: null, //风速数组
  20. wd: null, //风向数组
  21. image: null, //风羽图标所在图片
  22. interval: 1, //风羽绘制间隔(控制风羽疏密程度)
  23. timeOutId: null,
  24. elem: 'WS',
  25. elem2: 'WD',
  26. level: null,
  27. levelName: {
  28. '9999': '10米',
  29. '0925': '925hPa',
  30. '0850': '850hPa',
  31. '0700': '700hPa',
  32. '0500': '500hPa'
  33. },
  34. buttons: {
  35. '9999': null,
  36. '0925': null,
  37. '0850': null,
  38. '0700': null,
  39. '0500': null
  40. },
  41. isHide: false,
  42. getData: function () { //获取风羽数据
  43. var dateStr = meteo.c.time.getTime();
  44. // var dateStr = '2018-01-07 14:00:00';
  45. var level = airPlume.level == '9999' ? '1000' : airPlume.level;
  46. var vti = meteo.c.time.getVti();
  47. var params = {
  48. dateStr: dateStr,
  49. vti: vti,
  50. elem: airPlume.elem,
  51. level: level
  52. }
  53. meteo.c.http.httpFunction(meteo.c.http.tData, null, params, function (json) {
  54. airPlume.slat = json.slat;
  55. airPlume.slng = json.slng;
  56. airPlume.elat = json.elat;
  57. airPlume.elng = json.elng;
  58. airPlume.delta = json.delta;
  59. airPlume.rowNum = json.rowNum;
  60. airPlume.colNum = json.colNum;
  61. airPlume.ws = json.vals;
  62. params.elem = airPlume.elem2;
  63. meteo.c.http.httpFunction(meteo.c.http.tData, null, params, function (json) {
  64. airPlume.wd = json.vals;
  65. meteo.c.title.updateTitle(airPlume.id,
  66. meteo.c.process.setTitleTime(json.odate, json.vti, airPlume.title, airPlume.levelName[airPlume.level]));
  67. $('#meteo-video-query-startDate').val(json.odate);
  68. airPlume.showAirplume();
  69. }, function () {
  70. // ONEMAP.C.publisher.publish({ type: 'warning', message: '暂无当前时次/层次风羽WD数据' }, 'noteBar::add');
  71. // meteo.c.title.updateTitle(airPlume.id, '暂无当前时次/层次风羽WD数据');
  72. // if (airPlume.layer.cLayer) {
  73. //
  74. // } else {
  75. // airPlume.close();
  76. // }
  77. });
  78. }, function () {
  79. // ONEMAP.C.publisher.publish({ type: 'warning', message: '暂无当前时次/层次风羽WS数据' }, 'noteBar::add');
  80. // meteo.c.title.updateTitle(airPlume.id, '暂无当前时次/层次风羽WS数据');
  81. // if (airPlume.layer.cLayer) {
  82. //
  83. // } else {
  84. // airPlume.close();
  85. // }
  86. });
  87. },
  88. showAirplume: function () { //在当前显示区域内绘制风羽
  89. if (!airPlume.layer) {
  90. return;
  91. }
  92. var zoom = meteo.c.map.getZoom();
  93. // airPlume.getAirPlumeLevel(zoom);
  94. var interval = zoom < 3 ? 8 :
  95. zoom < 4 ? 6 :
  96. zoom < 5 ? 4 :
  97. zoom < 6 ? 2 : 1;
  98. // var se = airPlume.getBounds();
  99. var se = meteo.c.map.getBounds();
  100. var layerId = meteo.c.map.createLayer();
  101. var layer = map2DViewer.groups[layerId];
  102. //------------------------------
  103. //计算当前屏幕内显示的风羽索引
  104. // var istart = se[0] - airPlume.slat / airPlume.delta >> 0;
  105. var istart = (airPlume.elat - se[2]) / airPlume.delta >> 0;
  106. var jstart = (se[1] - airPlume.slng) / airPlume.delta >> 0;
  107. if (istart < 0) istart = 0;
  108. if (jstart < 0) jstart = 0;
  109. var row = Math.abs(se[0] - airPlume.elat) / airPlume.delta + 1;
  110. var col = Math.abs(se[3] - airPlume.slng) / airPlume.delta + 1;
  111. if (row > airPlume.rowNum) row = airPlume.rowNum;
  112. if (col > airPlume.colNum) col = airPlume.colNum;
  113. for (var i = istart; i < row; i += interval) {
  114. for (var j = jstart; j < col; j += interval) {
  115. var lng = airPlume.slng + j * airPlume.delta;
  116. var lat = airPlume.elat - i * airPlume.delta;
  117. var ws = airPlume.ws[i][j]
  118. var wd = airPlume.wd[i][j]
  119. var icon = airPlume.getIcon(ws, wd, 30);
  120. L.marker([lat, lng], {icon: icon}).addTo(layer);
  121. }
  122. }
  123. if (!airPlume.layer || !airPlume.layer.tLayer || airPlume.isHide) {
  124. meteo.c.map.removeLayer(layerId);
  125. return;
  126. }
  127. if (airPlume.layer.cLayer != null) {
  128. meteo.c.map.removeLayer(airPlume.layer.cLayer);
  129. }
  130. airPlume.layer.cLayer = layerId;
  131. if (airPlume.timeOutId) airPlume.timeOutId = null;
  132. },
  133. getIcon: function (ws, wd, size) { //获得风羽图标
  134. var width = size * 1.2;
  135. var a = size * 0.6;
  136. var b = size / 2;
  137. var canvas = document.createElement('canvas');
  138. canvas.width = width;
  139. canvas.height = width;
  140. if (canvas.getContext) {
  141. //获取对应的CanvasRenderingContext2D对象(画笔)
  142. var ctx = canvas.getContext("2d");
  143. ctx.save();
  144. ctx.translate(a, a);
  145. ctx.rotate(wd * Math.PI / 180);
  146. ctx.translate(-a, -a);
  147. // var as = getWindImageX(ws);
  148. // var bs = getWindImageY(ws, false);
  149. ctx.drawImage(airPlume.image, airPlume.getWindImageX(ws), airPlume.getWindImageY(ws, false), 15, 31,
  150. a - b / 2, a - b, b, size);
  151. ctx.restore();
  152. var url = canvas.toDataURL('image/png');
  153. return L.icon({
  154. iconUrl: url,
  155. iconSize: [size, size],
  156. iconAnchor: [size / 2, size / 2],
  157. });
  158. }
  159. return null;
  160. },
  161. getWindImageX: function (ws) {
  162. var index = ws > 72 ? 72 : ws;//最大72
  163. index = index < 0 ? 0 : index; //最小为0,同时0与1为同一张图片
  164. if (index < 3) { //当ws为1(包括0),取第0张图片 ws为2时,取第一张
  165. index = index >= 2 ? 1 : 0;
  166. } else {
  167. index = ((index + 1) / 2) >> 0;// 3和4为风速4,即第三张,则取角标2 依次类推
  168. }
  169. index = index % 10;
  170. return index * 16;
  171. },
  172. getWindImageY: function (ws, isGray) {
  173. var index = ws > 72 ? 72 : ws; //最大72
  174. index = index < 0 ? 0 : index; //最小为0,同时0与1为同一张图片
  175. if (ws < 3) { //当ws为1(包括0),取第0张图片 ws为2时,取第一张
  176. index = ws >= 2 ? 1 : 0;
  177. } else {
  178. index = ((ws + 1) / 2) >> 0;// 3和4为风速4,即第三张,则取角标2 依次类推
  179. }
  180. index = (index / 10) >> 0;
  181. if (isGray) {
  182. return index * 32 + 128;
  183. }
  184. return index * 32;
  185. },
  186. getAirPlumeLevel: function (zoom) { //根据地图缩放等级获取风羽疏密等级
  187. // var zoom = map2DViewer.map.getZoom();
  188. airPlume.interval = zoom < 3 ? 18 :
  189. zoom < 4 ? 12 :
  190. zoom < 5 ? 6 :
  191. zoom < 6 ? 2 : 1;
  192. },
  193. getBounds: function () { //获取当前显示范围
  194. var se = [];
  195. se.push(map2DViewer.map.getBounds().getSouthWest().lat);
  196. se.push(map2DViewer.map.getBounds().getSouthWest().lng);
  197. se.push(map2DViewer.map.getBounds().getNorthEast().lat);
  198. se.push(map2DViewer.map.getBounds().getNorthEast().lng);
  199. return se;
  200. },
  201. create: function () {
  202. airPlume.layer = {
  203. tLayer: meteo.c.map.createLayer(),
  204. cLayer: null,
  205. }
  206. },
  207. remove: function () {
  208. if (airPlume.layer) {
  209. meteo.c.map.removeLayer(airPlume.layer.tLayer);
  210. meteo.c.map.removeLayer(airPlume.layer.cLayer);
  211. airPlume.layer = null;
  212. }
  213. },
  214. show: function () {
  215. airPlume.isHide = false
  216. airPlume.showAirplume();
  217. },
  218. hide: function () {
  219. airPlume.isHide = true;
  220. if (airPlume.layer) {
  221. meteo.c.map.removeLayer(airPlume.layer.cLayer);
  222. airPlume.layer.cLayer = null;
  223. }
  224. },
  225. open: function () {
  226. if(ONEMAP.M.myLayers.checkLength() >= map23DConfig.layerMaxLength) {
  227. ONEMAP.C.publisher.publish({ type: 'warning', message: '图层数量已达上限' }, 'noteBar::add');
  228. return;
  229. }
  230. //-------------创建图层------------------
  231. if (airPlume.layer) {
  232. airPlume.close();
  233. }
  234. airPlume.create();
  235. //----------------图层管理-------------------
  236. var options = {
  237. action: "add",
  238. // mod: "qixiang",
  239. DOM: {
  240. guid: airPlume.layer.tLayer,
  241. type: "group",
  242. name: airPlume.title,
  243. },
  244. }
  245. var guid = ONEMAP.M.myLayers.myLayerControl(options);
  246. ONEMAP.C.publisher.subscribe(function (option) {
  247. switch (option.action) {
  248. case 'remove':
  249. airPlume.close();
  250. break;
  251. case 'opacity':
  252. if (option.options.opacity) {
  253. airPlume.show();
  254. } else {
  255. airPlume.hide();
  256. }
  257. break;
  258. }
  259. }, guid);
  260. //------------------勾选选择框及添加标题-------------------
  261. airPlume.buttons[airPlume.level].parent().addClass('current');
  262. meteo.c.title.addTitle(airPlume.id);
  263. meteo.c.time.open();
  264. //----------------------获取数据----------------------------
  265. airPlume.getData();
  266. //-----------------第一次开启功能时添加动态绘制--------------------
  267. // if (airPlume.isInit) return;
  268. // airPlume.isInit = true;
  269. // map2DViewer.map.on("moveend", function (e) {
  270. // if (airPlume.layer && airPlume.layer.cLayer) {
  271. // if (airPlume.timeOutId) { //如果有未开始的风羽绘制,就取消对应任务
  272. // window.clearTimeout(airPlume.timeOutId);
  273. // }
  274. // airPlume.timeOutId = window.setTimeout(function () {
  275. // airPlume.showAirplume();
  276. // }, 800)
  277. // }
  278. // });
  279. },
  280. close: function () { //关闭功能调用
  281. var options = {
  282. action: "remove",
  283. DOMid: airPlume.layer.tLayer,
  284. }
  285. ONEMAP.M.myLayers.myLayerControl(options);
  286. airPlume.buttons[airPlume.level].parent().removeClass('current');
  287. meteo.c.title.removeTitle(airPlume.id);
  288. meteo.c.time.close();
  289. airPlume.level = null;
  290. airPlume.remove();
  291. },
  292. onMove: function () { //移动地图时触发,控制当前是否需要重新绘制
  293. if (airPlume.layer && !airPlume.isHide && meteo.c.map.mapType == '2d') {
  294. if (airPlume.timeOutId) { //如果有未开始的风羽绘制,就取消对应任务
  295. window.clearTimeout(airPlume.timeOutId);
  296. }
  297. airPlume.timeOutId = window.setTimeout(function () {
  298. airPlume.showAirplume();
  299. }, 800)
  300. }
  301. },
  302. update: function () { //用于时间变化时更新数据
  303. if (!airPlume.layer || airPlume.isHide) return;
  304. // var option = {
  305. // action: 'update',
  306. // DOMid: airPlume.layer.tLayer,
  307. // DOM: {
  308. // name: '风羽' + meteo.c.time.getTimeOnTitle()
  309. // }
  310. // }
  311. // ONEMAP.M.myLayers.myLayerControl(option);
  312. airPlume.getData()
  313. },
  314. updateLevel: function () {
  315. airPlume.buttons[airPlume.level].parent().siblings().removeClass('current');
  316. airPlume.buttons[airPlume.level].parent().addClass('current');
  317. airPlume.getData();
  318. },
  319. click: function (level) {
  320. if (airPlume.level && level != airPlume.level) {
  321. airPlume.level = level;
  322. airPlume.updateLevel();
  323. } else {
  324. airPlume.level = level;
  325. if (airPlume.layer) {
  326. airPlume.close();
  327. } else {
  328. airPlume.open();
  329. }
  330. }
  331. },
  332. init: function () {
  333. airPlume.image = new Image();
  334. airPlume.image.src = meteo.c.http.myImageUrlJs + "windy.png";
  335. var buttons = $('.meteo-button-799');
  336. airPlume.buttons['9999'] = buttons.eq(16);
  337. airPlume.buttons['0925'] = buttons.eq(17);
  338. airPlume.buttons['0850'] = buttons.eq(18);
  339. airPlume.buttons['0700'] = buttons.eq(19);
  340. airPlume.buttons['0500'] = buttons.eq(20);
  341. }
  342. }
  343. meteo.f.air = airPlume;
  344. return meteo.f.air;
  345. })