vector.js 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438
  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. img.src = path;
  191. img.onload = function () {
  192. // 增加底色
  193. if (option.background) {
  194. context.beginPath();
  195. context.rect(0, 0, canvas.width, canvas.height);
  196. context.fillStyle = option.background;
  197. // context.fillStyle = "transparent";
  198. context.fill();
  199. context.closePath();
  200. }
  201. //
  202. context.drawImage(img, 0, 0);
  203. var marker = option.watermark || "";
  204. if (marker) {
  205. context.font = "18px 微软雅黑";
  206. context.fillStyle = "rgba(12, 0, 70, 0.5)";
  207. var textWidth = context.measureText(marker).width,
  208. textHegith = 50,
  209. pk = 1.2,
  210. rotate = (option.rotation || -45) * Math.PI / 180,
  211. sinReg = Math.sin(rotate),
  212. cosReg = Math.cos(rotate),
  213. width = Math.abs(canvas.width * cosReg) + Math.abs(canvas.height * sinReg),
  214. height = Math.abs(canvas.height * cosReg) + Math.abs(canvas.width * sinReg);
  215. var xf = Math.ceil(width / textWidth * pk);
  216. var yf = Math.ceil(height / textHegith);
  217. context.rotate(rotate);
  218. for (var i = 0; i < yf; i++) {
  219. for (var k = 0; k < xf; k++) {
  220. context.fillText(marker, textWidth * k * pk - canvas.height * cosReg, textHegith * i)
  221. }
  222. }
  223. }
  224. document.body.appendChild(canvas);
  225. _exportPath = canvas.toDataURL(MIMEType || 'image/png', 1)
  226. typeof handler === 'function' && handler(_exportPath)
  227. document.body.removeChild(canvas)
  228. }
  229. return new Promise(function (resolve, reject) {
  230. handler = resolve
  231. })
  232. }
  233. /**
  234. * 加载
  235. * @return {[type]} [description]
  236. */
  237. async function add3DVECTOR(options, style) {
  238. // var guid = map23DControl.buildGuid('VECTOR-3DData');
  239. var guid = "VECTOR--" + options.layerInfo.id
  240. let img = null;
  241. if (style.point) {
  242. // 获取svg
  243. let svg = getAndSetSVGElement(style.point.photo, style.point.color)
  244. // console.log(svg)
  245. img = await svgToImg(svg);
  246. // img = await export2Base64Img(img, "", {
  247. // background: "#ffffff00"
  248. // });
  249. }
  250. Cesium.GeoJsonDataSource.load(options.geo).then(
  251. function (dataSource) {
  252. dataSource.name = guid;
  253. map3DViewer.map.dataSources.add(dataSource);
  254. modValue.VECTOR[guid] = dataSource;
  255. var entities = dataSource.entities.values;
  256. for (var i = 0; i < entities.length; i++) {
  257. var entity = entities[i];
  258. if (entity.billboard) {
  259. entity.billboard = undefined;
  260. // entity.point = new Cesium.PointGraphics({
  261. // show: true,
  262. // pixelSize: 15,
  263. // color: Cesium.Color.fromCssColorString("#aed0ff"),
  264. // outlineColor: Cesium.Color.fromCssColorString("#3388ff"),
  265. // outlineWidth: 2,
  266. // heightReference: Cesium.HeightReference.CLAMP_TO_GROUND,
  267. // scaleByDistance: new Cesium.NearFarScalar(10000, 1, 20000, 0.5),
  268. // // translucencyByDistance: new Cesium.NearFarScalar(1500, 1, 20000, 0.2),
  269. // // distanceDisplayCondition: new Cesium.DistanceDisplayCondition(0, 20000)
  270. // })
  271. entity.billboard = new Cesium.BillboardGraphics({
  272. image: img,
  273. width: 50,
  274. height: 50,
  275. pixelOffset: new Cesium.Cartesian2(0, -25),
  276. heightReference: Cesium.HeightReference.CLAMP_TO_GROUND,
  277. // scaleByDistance: new Cesium.NearFarScalar(10000, 1, 20000, 0.75),
  278. })
  279. }
  280. if (entity.polyline) {
  281. entity.polyline.width = style.polyline.width;
  282. entity.polyline.material = Cesium.Color.fromCssColorString(style.polyline.color).withAlpha(style.polyline.alpha); // 颜色
  283. }
  284. if (entity.polygon) {
  285. entity.polygon.height = 0.2;
  286. entity.polygon.outline = true; // 边框是否显示
  287. entity.polygon.outlineColor = Cesium.Color.fromCssColorString(style.polygon.outerColor); // 边框颜色
  288. entity.polygon.outlineWidth = style.polygon.outerWidth; // 边框宽度
  289. entity.polygon.material = Cesium.Color.fromCssColorString(style.polygon.innerColor).withAlpha(style.polygon.alpha);// 填充色
  290. }
  291. entity.layerId = guid
  292. entity.mod = "vectorMod"
  293. }
  294. var extentR = turf.bbox(options.geo);
  295. map3DViewer.map.camera.flyTo({
  296. destination: Cesium.Rectangle.fromDegrees(extentR[0] - 0.04, extentR[1] - 0.04, extentR[2] + 0.04, extentR[3] + 0.04),
  297. });
  298. modValue.VECTOR[guid + "_extent"] = extentR;
  299. }
  300. );
  301. return guid;
  302. };
  303. function removeVECTOR(options) {
  304. map3DViewer.map.dataSources.remove(map3DViewer.map.dataSources.getByName(options.guid)[0]);
  305. delete modValue.VECTOR[options.guid];
  306. delete modValue.VECTOR[options.guid + "_extent"];
  307. if (Object.getOwnPropertyNames(modValue.VECTOR).length == 0) {
  308. closeClick();
  309. }
  310. }
  311. function opacityVECTOR(options) {
  312. modValue.VECTOR[options.guid].entities.values.map(function (entity) {
  313. if (entity.point) {
  314. entity.point = new Cesium.PointGraphics({
  315. show: true,
  316. pixelSize: 15,
  317. heightReference: Cesium.HeightReference.CLAMP_TO_GROUND,
  318. color: Cesium.Color.fromCssColorString("#aed0ff").withAlpha(options.options.opacity),
  319. outlineColor: Cesium.Color.fromCssColorString("#3388ff").withAlpha(options.options.opacity),
  320. outlineWidth: 2,
  321. scaleByDistance: new Cesium.NearFarScalar(10000, 1, 20000, 0.5),
  322. })
  323. }
  324. if (entity.polyline) {
  325. entity.polyline.material = Cesium.Color.fromCssColorString("#3388ff").withAlpha(options.options.opacity); // 颜色
  326. }
  327. if (entity.polygon) {
  328. entity.polygon.outlineColor = Cesium.Color.fromCssColorString("#3388ff").withAlpha(options.options.opacity); // 边框颜色
  329. entity.polygon.material = Cesium.Color.fromCssColorString("#aed0ff").withAlpha(options.options.opacity);// 填充色
  330. }
  331. })
  332. }
  333. function controlShowVECTOR(options) {
  334. if (options.options.show)
  335. modValue.VECTOR[options.guid].show = true
  336. if (!options.options.show)
  337. modValue.VECTOR[options.guid].show = false
  338. }
  339. function locationVECTOR(options) {
  340. let extentR = modValue.VECTOR[options.guid + "_extent"]
  341. map3DViewer.map.camera.flyTo({
  342. destination: Cesium.Rectangle.fromDegrees(extentR[0], extentR[1], extentR[2], extentR[3]),
  343. });
  344. }
  345. function openClick() {
  346. if (modValue.handler) return;
  347. // 绑定点击事件
  348. modValue.handler = new Cesium.ScreenSpaceEventHandler(map3DViewer.map.canvas);
  349. modValue.handler.setInputAction(function (movement) {
  350. if (ONEMAP.M.toolsBar.status.toolsShow) return;
  351. var pick = map3DViewer.map.scene.pick(movement.position); // 拾取鼠标所在的entity
  352. if (Cesium.defined(pick)) {
  353. let entity = pick.id;
  354. if (entity.mod && entity.mod == "vectorMod") {
  355. let properties = entity.properties.getValue();
  356. openEntityPropertiesDialog(properties, entity.layerId);
  357. }
  358. }
  359. }, Cesium.ScreenSpaceEventType.LEFT_CLICK)
  360. }
  361. function closeClick() {
  362. if (modValue.handler) {
  363. modValue.handler.removeInputAction(Cesium.ScreenSpaceEventType.LEFT_CLICK)
  364. modValue.handler = null;
  365. }
  366. }
  367. function openEntityPropertiesDialog(properties, layerId) {
  368. if ($("#vectorInfoModal").length != 1) {
  369. $('body').append(dialogLayout);
  370. //拖拽
  371. $("#vectorInfoModal .popup-ct").dragmove($('#vectorInfoModal'));
  372. } else {
  373. $("#vectorInfoForm table").empty();
  374. }
  375. $("#vectorInfoModal .title").text(properties.Name)
  376. let html = `<tr><td><p>字段</p></td><td>值</td></tr>`
  377. $("#vectorInfoForm table").append(html)
  378. Object.getOwnPropertyNames(properties).map(function (field) {
  379. let html = `<tr><td><p>${field}</p></td><td>${properties[field]}</td></tr>`
  380. $("#vectorInfoForm table").append(html)
  381. })
  382. modValue.nowOpenDialogLayerId = layerId
  383. $("#vectorInfoModal .close").bind('click', function () {
  384. closeEntityPropertiesDialog();
  385. });
  386. }
  387. function closeEntityPropertiesDialog() {
  388. $("#vectorInfoModal").remove()
  389. }
  390. return ONEMAP.M.threeData = {
  391. add: add,
  392. remove: remove,
  393. }
  394. });