vector.js 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479
  1. /**
  2. * [ONEMAP.M.projectController]
  3. * @return {[object]}
  4. */
  5. define([
  6. 'html!templates/menu/vectorInfo',
  7. 'css!styles/menu/vectorInfo',
  8. ], function (dialogLayout) {
  9. /**
  10. * 初始化并订阅事件
  11. * @return {[type]} [description]
  12. */
  13. /**
  14. * 模块数据 用于数据存储和外部调用
  15. * @type {Object}
  16. * 数据存放
  17. */
  18. var modValue = {
  19. VECTOR: {},
  20. handler: null,
  21. nowOpenDialogLayerId: null,
  22. }
  23. function add(item, cancelSelected) {
  24. modValue.cancelSelected = cancelSelected
  25. // if (ONEMAP.M.myLayers.checkLength() >= map23DConfig.layerMaxLength) {
  26. // ONEMAP.C.publisher.publish({ type: 'warning', message: '图层数量已达上限' }, 'noteBar::add');
  27. // modValue.cancelSelected(item.id)
  28. // return;
  29. // }
  30. var modelData = {
  31. "category": "倾斜摄影",
  32. "info": "",
  33. "name": item.title,
  34. "layerInfo": item
  35. }
  36. var options = {};
  37. let request1 = fetch(onemapUrlConfig.DMS_URL + '/dms/content/selectContentList', {
  38. method: "POST",
  39. headers: {
  40. "Content-Type": "application/x-www-form-urlencoded",
  41. "token": localStorage.getItem("systemToken"),
  42. },
  43. mode: "cors",
  44. body: "columnId=" + modelData.layerInfo.id
  45. }).then(resp => resp.json())
  46. let request2 = fetch(onemapUrlConfig.DMS_URL + '/dms/content/getVectorData', {
  47. method: "POST",
  48. headers: {
  49. "Content-Type": "application/x-www-form-urlencoded",
  50. "token": localStorage.getItem("systemToken"),
  51. },
  52. mode: "cors",
  53. body: "columnId=" + modelData.layerInfo.id + "&token=" + localStorage.getItem("systemToken")
  54. // body: "columnId=" + modelData.layerInfo.id
  55. }).then(resp => resp.json())
  56. // 创建一个Promise数组
  57. const promises = [request1, request2]
  58. // 使用Promise.all来等待所有请求完成
  59. Promise.all(promises).then(responses => {
  60. // 所有请求都成功完成时,这里的代码会被执行
  61. // `responses`是一个数组,包含了所有请求的响应结果
  62. // console.log(responses);
  63. let styleRes = responses[0]
  64. let geojsonRes = responses[1]
  65. if (styleRes.code != 200) {
  66. ONEMAP.C.publisher.publish({
  67. type: 'warning',
  68. message: styleRes.message,
  69. }, 'noteBar::add');
  70. return
  71. }
  72. if (geojsonRes.code != undefined) {
  73. ONEMAP.C.publisher.publish({
  74. type: 'warning',
  75. message: geojsonRes.message,
  76. }, 'noteBar::add');
  77. return
  78. }
  79. if (geojsonRes.features.length == 0) {
  80. ONEMAP.C.publisher.publish({
  81. type: 'warning',
  82. message: "当前图层无数据!",
  83. }, 'noteBar::add');
  84. return
  85. }
  86. let style = JSON.parse(styleRes.content.data[0].c_style).style
  87. modelData.geo = geojsonRes
  88. let promise = add3DVECTOR(modelData, style);
  89. promise.then(function (guid) {
  90. options = {
  91. action: "add",
  92. DOM: {
  93. guid: guid,
  94. type: "VECTOR",
  95. name: item.title,
  96. },
  97. mod: "VECTOR"
  98. }
  99. if (!guid) return
  100. ONEMAP.M.myLayers.myLayerControl(options); // 添加信息到“我的图层”
  101. ONEMAP.C.publisher.subscribe(layerAction, guid);
  102. openClick();
  103. })
  104. }).catch(error => {
  105. // 如果任何一个请求失败,这里的代码会被执行
  106. // console.error(error);
  107. ONEMAP.C.publisher.publish({
  108. type: 'warning',
  109. message: error,
  110. }, 'noteBar::add');
  111. });
  112. }
  113. function remove(options) {
  114. var guid = options.guid ? options.guid : "VECTOR--" + options.id;
  115. removeVECTOR({ guid: guid })
  116. ONEMAP.M.myLayers.myLayerControl({
  117. action: "remove",
  118. DOMid: guid
  119. }); // 移除数据层
  120. if (guid == modValue.nowOpenDialogLayerId) {
  121. closeEntityPropertiesDialog();
  122. modValue.nowOpenDialogLayerId = null;
  123. }
  124. }
  125. function layerAction(options) {
  126. if (options.guid.split("--")[0] == "VECTOR") {
  127. if (options.action == "remove") {
  128. // removeVECTOR(options.guid)
  129. remove(options)
  130. modValue.cancelSelected(Number(options.guid.split("--")[1]));
  131. } else if (options.action == "opacity") {
  132. opacityVECTOR(options)
  133. } else if (options.action == "controlShow") {
  134. controlShowVECTOR(options)
  135. } else if (options.action == "up" || options.action == "down") {
  136. } else if (options.action == "location") {
  137. locationVECTOR(options)
  138. }
  139. }
  140. }
  141. // 获取 svg 的元素源码
  142. function getAndSetSVGElement(svgUrl, color, token) {
  143. var oReq = new XMLHttpRequest();
  144. oReq.open("GET", svgUrl, false);
  145. oReq.setRequestHeader("Content-type", "application/json");
  146. // oReq.setRequestHeader("token", token);
  147. oReq.send(JSON.stringify());
  148. let parser = new DOMParser();
  149. let xmlDom = parser.parseFromString(oReq.responseText, "text/html");
  150. xmlDom.querySelector("g>path").setAttribute("fill", color);
  151. return new XMLSerializer().serializeToString(xmlDom.querySelector("svg"));
  152. }
  153. function svgToImg(svgStr) {
  154. const blob = new Blob([svgStr], { type: 'image/svg+xml;charset=utf-8' });
  155. // 创建一个 FileReader 对象来读取 Blob
  156. const reader = new FileReader();
  157. reader.readAsDataURL(blob);
  158. // 当 FileReader 完成读取时,它会触发 'load' 事件
  159. return new Promise((resolve) => {
  160. reader.onloadend = function () {
  161. resolve(reader.result)
  162. };
  163. })
  164. }
  165. // function reEncode(data) {
  166. // return decodeURIComponent(
  167. // encodeURIComponent(data).replace(/%([0-9A-F]{2})/g, (match, p1) => {
  168. // const c = String.fromCharCode(`0x${p1}`);
  169. // return c === '%' ? '%25' : c;
  170. // })
  171. // )
  172. // }
  173. function export2Base64Img(path, MIMEType, option) {
  174. // var serializer = new XMLSerializer();
  175. // var source = serializer.serializeToString(svgDom);
  176. // 方式一: unescape(encodeURIComponent(txt))
  177. // var path = "data:image/svg+xml;base64," + window.btoa(unescape(encodeURIComponent(source)));
  178. // 方式二: decodeURIComponent(encodeURIComponent(txt))
  179. // var path = "data:image/svg+xml;base64," + window.btoa(reEncode(source));
  180. var canvas = document.createElement("canvas"),
  181. context = canvas.getContext("2d"),
  182. img = new Image(),
  183. pixelRatio = window.devicePixelRatio || 1,
  184. _exportPath, handler
  185. option = option || {};
  186. // canvas.width = parseFloat(svgDom.getAttribute('width')); // * pixelRatio
  187. // canvas.height = parseFloat(svgDom.getAttribute('height')); // * pixelRatio
  188. // canvas.width = 500
  189. // canvas.height = 500
  190. canvas.width = option.width
  191. canvas.height = option.height
  192. img.src = path;
  193. img.onload = function () {
  194. // 增加底色
  195. if (option.background) {
  196. context.beginPath();
  197. context.rect(0, 0, canvas.width, canvas.height);
  198. context.fillStyle = option.background;
  199. // context.fillStyle = "transparent";
  200. context.fill();
  201. context.closePath();
  202. }
  203. //
  204. context.drawImage(img, 0, 0);
  205. var marker = option.watermark || "";
  206. if (marker) {
  207. context.font = "18px 微软雅黑";
  208. context.fillStyle = "rgba(12, 0, 70, 0.5)";
  209. var textWidth = context.measureText(marker).width,
  210. textHegith = 50,
  211. pk = 1.2,
  212. rotate = (option.rotation || -45) * Math.PI / 180,
  213. sinReg = Math.sin(rotate),
  214. cosReg = Math.cos(rotate),
  215. width = Math.abs(canvas.width * cosReg) + Math.abs(canvas.height * sinReg),
  216. height = Math.abs(canvas.height * cosReg) + Math.abs(canvas.width * sinReg);
  217. var xf = Math.ceil(width / textWidth * pk);
  218. var yf = Math.ceil(height / textHegith);
  219. context.rotate(rotate);
  220. for (var i = 0; i < yf; i++) {
  221. for (var k = 0; k < xf; k++) {
  222. context.fillText(marker, textWidth * k * pk - canvas.height * cosReg, textHegith * i)
  223. }
  224. }
  225. }
  226. document.body.appendChild(canvas);
  227. _exportPath = canvas.toDataURL(MIMEType || 'image/png', 1)
  228. typeof handler === 'function' && handler(_exportPath)
  229. document.body.removeChild(canvas)
  230. }
  231. return new Promise(function (resolve, reject) {
  232. handler = resolve
  233. })
  234. }
  235. /**
  236. * 加载
  237. * @return {[type]} [description]
  238. */
  239. async function add3DVECTOR(options, style) {
  240. // var guid = map23DControl.buildGuid('VECTOR-3DData');
  241. var guid = "VECTOR--" + options.layerInfo.id
  242. let img = null;
  243. if (style.point) {
  244. if (style.point.photo.indexOf(".svg") > -1) {
  245. // 获取svg
  246. let svg = getAndSetSVGElement(style.point.photo, style.point.color)
  247. // console.log(svg)
  248. img = await svgToImg(svg);
  249. if (style.point.photo.indexOf("coordinate") == -1) {
  250. img = await export2Base64Img(img, "", {
  251. background: "#ffffff00",
  252. width: 200,
  253. height: 200
  254. });
  255. } else {
  256. img = await export2Base64Img(img, "", {
  257. background: "#ffffff00",
  258. width: 500,
  259. height: 500
  260. });
  261. }
  262. } else {
  263. img = style.point.photo;
  264. }
  265. }
  266. Cesium.GeoJsonDataSource.load(options.geo).then(
  267. function (dataSource) {
  268. dataSource.name = guid;
  269. map3DViewer.map.dataSources.add(dataSource);
  270. modValue.VECTOR[guid] = dataSource;
  271. var entities = dataSource.entities.values;
  272. for (var i = 0; i < entities.length; i++) {
  273. var entity = entities[i];
  274. if (entity.billboard) {
  275. entity.billboard = undefined;
  276. // entity.point = new Cesium.PointGraphics({
  277. // show: true,
  278. // pixelSize: 15,
  279. // color: Cesium.Color.fromCssColorString("#aed0ff"),
  280. // outlineColor: Cesium.Color.fromCssColorString("#3388ff"),
  281. // outlineWidth: 2,
  282. // heightReference: Cesium.HeightReference.CLAMP_TO_GROUND,
  283. // scaleByDistance: new Cesium.NearFarScalar(10000, 1, 20000, 0.5),
  284. // // translucencyByDistance: new Cesium.NearFarScalar(1500, 1, 20000, 0.2),
  285. // // distanceDisplayCondition: new Cesium.DistanceDisplayCondition(0, 20000)
  286. // })
  287. entity.billboard = new Cesium.BillboardGraphics({
  288. image: img,
  289. width: 28,
  290. height: 28,
  291. pixelOffset: new Cesium.Cartesian2(0, -25),
  292. heightReference: Cesium.HeightReference.CLAMP_TO_GROUND,
  293. // scaleByDistance: new Cesium.NearFarScalar(10000, 1, 20000, 0.75),
  294. })
  295. }
  296. if (entity.polyline) {
  297. entity.polyline.width = style.polyline.width;
  298. entity.polyline.material = Cesium.Color.fromCssColorString(style.polyline.color).withAlpha(style.polyline.alpha); // 颜色
  299. }
  300. if (entity.polygon) {
  301. entity.polygon.height = 0;
  302. entity.polygon.outline = true; // 边框是否显示
  303. entity.polygon.outlineColor = Cesium.Color.fromCssColorString(style.polygon.outerColor); // 边框颜色
  304. entity.polygon.outlineWidth = style.polygon.outerWidth; // 边框宽度
  305. entity.polygon.material = Cesium.Color.fromCssColorString(style.polygon.innerColor).withAlpha(style.polygon.alpha);// 填充色
  306. // entity.polyline = new Cesium.PolylineGraphics({
  307. // position: entity.polygon.hierarchy.getValue().positions.concat([]),
  308. // width: style.polygon.outerWidth,
  309. // material: Cesium.Color.fromCssColorString(style.polygon.outerColor), // 颜色
  310. // });
  311. let outline = map3DViewer.map.entities.add({
  312. name: "线",
  313. polyline: {
  314. //经纬度数组转世界坐标,带高度的话是fromDegreesArrayHeights
  315. positions: entity.polygon.hierarchy.getValue().positions.concat([]),
  316. width: style.polygon.outerWidth,
  317. material: Cesium.Color.fromCssColorString(style.polygon.outerColor),
  318. }
  319. });
  320. entity.outline = outline;
  321. }
  322. entity.layerId = guid
  323. entity.mod = "vectorMod"
  324. }
  325. var extentR = turf.bbox(options.geo);
  326. map3DViewer.map.camera.flyTo({
  327. destination: Cesium.Rectangle.fromDegrees(extentR[0] - 0.04, extentR[1] - 0.04, extentR[2] + 0.04, extentR[3] + 0.04),
  328. });
  329. modValue.VECTOR[guid + "_extent"] = extentR;
  330. }
  331. );
  332. return guid;
  333. };
  334. function removeVECTOR(options) {
  335. let dataSource = map3DViewer.map.dataSources.getByName(options.guid)[0]
  336. var entities = dataSource.entities.values;
  337. for (var i = 0; i < entities.length; i++) {
  338. var entity = entities[i];
  339. if (entity.polygon) {
  340. map3DViewer.map.entities.remove(entity.outline);
  341. }
  342. }
  343. map3DViewer.map.dataSources.remove(dataSource);
  344. delete modValue.VECTOR[options.guid];
  345. delete modValue.VECTOR[options.guid + "_extent"];
  346. if (Object.getOwnPropertyNames(modValue.VECTOR).length == 0) {
  347. closeClick();
  348. }
  349. }
  350. function opacityVECTOR(options) {
  351. modValue.VECTOR[options.guid].entities.values.map(function (entity) {
  352. if (entity.point) {
  353. entity.point = new Cesium.PointGraphics({
  354. show: true,
  355. pixelSize: 15,
  356. heightReference: Cesium.HeightReference.CLAMP_TO_GROUND,
  357. color: Cesium.Color.fromCssColorString("#aed0ff").withAlpha(options.options.opacity),
  358. outlineColor: Cesium.Color.fromCssColorString("#3388ff").withAlpha(options.options.opacity),
  359. outlineWidth: 2,
  360. scaleByDistance: new Cesium.NearFarScalar(10000, 1, 20000, 0.5),
  361. })
  362. }
  363. if (entity.polyline) {
  364. entity.polyline.material = Cesium.Color.fromCssColorString("#3388ff").withAlpha(options.options.opacity); // 颜色
  365. }
  366. if (entity.polygon) {
  367. entity.polygon.outlineColor = Cesium.Color.fromCssColorString("#3388ff").withAlpha(options.options.opacity); // 边框颜色
  368. entity.polygon.material = Cesium.Color.fromCssColorString("#aed0ff").withAlpha(options.options.opacity);// 填充色
  369. }
  370. })
  371. }
  372. function controlShowVECTOR(options) {
  373. if (options.options.show)
  374. modValue.VECTOR[options.guid].show = true
  375. if (!options.options.show)
  376. modValue.VECTOR[options.guid].show = false
  377. }
  378. function locationVECTOR(options) {
  379. let extentR = modValue.VECTOR[options.guid + "_extent"]
  380. map3DViewer.map.camera.flyTo({
  381. destination: Cesium.Rectangle.fromDegrees(extentR[0], extentR[1], extentR[2], extentR[3]),
  382. });
  383. }
  384. function openClick() {
  385. if (modValue.handler) return;
  386. // 绑定点击事件
  387. modValue.handler = new Cesium.ScreenSpaceEventHandler(map3DViewer.map.canvas);
  388. modValue.handler.setInputAction(function (movement) {
  389. if (ONEMAP.M.toolsBar.status.toolsShow) return;
  390. var pick = map3DViewer.map.scene.pick(movement.position); // 拾取鼠标所在的entity
  391. if (Cesium.defined(pick)) {
  392. let entity = pick.id;
  393. if (entity.mod && entity.mod == "vectorMod") {
  394. let properties = entity.properties.getValue();
  395. openEntityPropertiesDialog(properties, entity.layerId);
  396. }
  397. }
  398. }, Cesium.ScreenSpaceEventType.LEFT_CLICK)
  399. }
  400. function closeClick() {
  401. if (modValue.handler) {
  402. modValue.handler.removeInputAction(Cesium.ScreenSpaceEventType.LEFT_CLICK)
  403. modValue.handler = null;
  404. }
  405. }
  406. function openEntityPropertiesDialog(properties, layerId) {
  407. if ($("#vectorInfoModal").length != 1) {
  408. $('body').append(dialogLayout);
  409. //拖拽
  410. $("#vectorInfoModal .popup-ct").dragmove($('#vectorInfoModal'));
  411. } else {
  412. $("#vectorInfoForm table").empty();
  413. }
  414. $("#vectorInfoModal .title").text(properties.Name)
  415. let html = `<tr><td><p>字段</p></td><td>值</td></tr>`
  416. $("#vectorInfoForm table").append(html)
  417. Object.getOwnPropertyNames(properties).map(function (field) {
  418. let html = `<tr><td><p>${field}</p></td><td>${properties[field]}</td></tr>`
  419. $("#vectorInfoForm table").append(html)
  420. })
  421. modValue.nowOpenDialogLayerId = layerId
  422. $("#vectorInfoModal .close").bind('click', function () {
  423. closeEntityPropertiesDialog();
  424. });
  425. }
  426. function closeEntityPropertiesDialog() {
  427. $("#vectorInfoModal").remove()
  428. }
  429. return ONEMAP.M.threeData = {
  430. add: add,
  431. remove: remove,
  432. }
  433. });