DrawPoint.js 35 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141
  1. /* 引入Cesium */
  2. // import * as Cesium from 'Cesium';
  3. import CreateRemindertip from "../common/ReminderTip.js";
  4. //点对象
  5. import PointObject from "../PointObject.js";
  6. /* 引入属性编辑框 */
  7. import DialogEditProperty from './CrEditProperty_Point.ce.vue';
  8. /* 引入组件注册 */
  9. import {
  10. defineCustomElement
  11. } from 'vue';
  12. /**
  13. * 设置附加参数
  14. * @ignore 生成方法时不对外公开
  15. * @param {JSON} params 参数
  16. */
  17. Cesium.Entity.prototype.setParams = function(params) {
  18. this._params = params;
  19. }
  20. /**
  21. * 获取附加参数
  22. * @ignore 生成方法时不对外公开
  23. */
  24. Cesium.Entity.prototype.getParams = function() {
  25. return this._params;
  26. }
  27. /**
  28. * 设置实体挂接的数据类型
  29. * @ignore 生成方法时不对外公开
  30. * @param {DrawPoint.DrawType} entityType 实体挂接的数据类型
  31. */
  32. Cesium.Entity.prototype.setEntityType = function(entityType) {
  33. this._entityType = entityType;
  34. }
  35. /**
  36. * 获取实体挂接的数据类型
  37. * @ignore 生成方法时不对外公开
  38. * @@return {DrawPoint.DrawType} 实体挂接的数据类型
  39. */
  40. Cesium.Entity.prototype.getEntityType = function(entityType) {
  41. return this._entityType;
  42. }
  43. /**
  44. * 设置实体是否可编辑
  45. * @ignore 生成方法时不对外公开
  46. * @param {Boolean} isEdit 是否可编辑
  47. */
  48. Cesium.Entity.prototype.setIsEdit = function(isEdit) {
  49. this._isEdit = isEdit;
  50. }
  51. /**
  52. * 获取实体是否可编辑
  53. * @ignore 生成方法时不对外公开
  54. * @return {Boolean} isEdit
  55. */
  56. Cesium.Entity.prototype.getIsEdit = function() {
  57. return this._isEdit;
  58. }
  59. /**
  60. * 绘制点文字小模型
  61. */
  62. class DrawPoint {
  63. /**
  64. * 默认初始化
  65. */
  66. constructor(viewer) {
  67. if (!viewer) throw new Cesium.DeveloperError('no viewer object!');
  68. this._viewer = viewer;
  69. /* 开启地形检测 必须开启 否则会导致获取地形高度时异常 导致鼠标移动时位置哆嗦 */
  70. this._viewer.scene.globe.depthTestAgainstTerrain = true;
  71. /* 取消地图右键点击事件 */
  72. this._viewer.cesiumWidget.screenSpaceEventHandler.removeInputAction(Cesium.ScreenSpaceEventType.LEFT_DOUBLE_CLICK);
  73. /* 实体数据集 */
  74. this._entities = [];
  75. //绘制点
  76. this._pointObject = new PointObject(viewer);
  77. }
  78. /**
  79. * 静态方法 初始化并获取属性编辑参数
  80. */
  81. static initEditPropertyParams() {
  82. return {
  83. id: undefined, //用于标识及传递当前编辑的实体类型 内容为DrawPoint.DrawType
  84. label: {
  85. text: '金田CIM三维基础平台', //文字内容
  86. font: 'Helvetica', //文字字体
  87. fontSize: 24, //文字字体大小
  88. bolder: false, //文字是否加粗
  89. italic: false, //文字是否倾斜
  90. fillColor: 'rgba(0,255,0,0.75)', //文字颜色
  91. showOutline: false, //是否显示描边线
  92. outlineWidth: 0, //描边线宽度
  93. outlineColor: 'rgba(255,255,255,1)', //描边线颜色
  94. showBackground: false, //是否显示背景
  95. backgroundPadding: 0, //以像素为单位指定水平和垂直背景填充。
  96. backgroundColor: 'rgba(255,255,255,1)', //背景颜色
  97. pixelOffsetX: 0, //横向偏移像素
  98. pixelOffsetY: 0 //纵向偏移像素
  99. },
  100. point: {
  101. color: 'rgba(0,255,0,0.75)', //点颜色
  102. pixelSize: 10, //点像素大小
  103. showOutline: false, //是否显示描边线
  104. outlineWidth: 0, //描边线宽度
  105. outlineColor: 'rgba(255,255,255,1)', //描边线颜色
  106. },
  107. billboard: {
  108. imgUrl: 'jt3dSDK/imgs/point/point3.png', //图片路径
  109. alpha: 1, //透明度
  110. scale: 1, //放大比例
  111. },
  112. model: {
  113. url: 'jt3dSDK/gltf/pyramid.glb', //模型路径
  114. alpha: 1, // 模型透明度
  115. showSilhouette: false, //是否显示模型轮廓
  116. silhouetteColor: 'rgba(255,255,255,1)', // 模型轮廓颜色[0~255,0~255,0~255,0~1]
  117. silhouetteSize: 0, //模型轮廓宽度
  118. minimumPixelSize: 128, // 模型最小刻度
  119. maximumScale: 20000, // 模型的最大比例尺大小,设置模型最大放大大小
  120. heading: 0.0, // 以弧度为单位的航向分量
  121. pitch: 0.0, //以弧度为单位的螺距分量
  122. roll: 0.0, // 以弧度为单位的滚动分量
  123. }
  124. }
  125. }
  126. /**
  127. * 世界坐标转换为经纬度坐标
  128. * @ignore 生成方法时不对外公开
  129. * @param {Cesium.Cartesian3} position 点
  130. */
  131. _cartesian3ToGeo(position) {
  132. let g = Cesium.Ellipsoid.WGS84.cartesianToCartographic(position);
  133. return {
  134. longitude: Cesium.Math.toDegrees(g.longitude),
  135. latitude: Cesium.Math.toDegrees(g.latitude),
  136. height: g.height,
  137. }
  138. }
  139. /**
  140. * 弧度转度
  141. * @ignore
  142. * @param {Number} arc 弧度
  143. * @return {Number} 角度
  144. */
  145. _arcToDegree(arc) {
  146. return arc / Math.PI * 180;
  147. }
  148. /**
  149. * 根据地形或实景或模型检测当前屏幕位置的经纬度及高度
  150. * @ignore
  151. * @param {JSON} screenPoint 屏幕坐标
  152. * @param {Number} screenPoint.x 屏幕坐标x
  153. * @param {Number} screenPoint.y 屏幕坐标y
  154. * @return {JSON} 位置信息{lng,lat,height}
  155. */
  156. _getScreenClickPositionAndHeight(screenPoint) {
  157. var lng = undefined,
  158. lat = undefined,
  159. height = undefined;
  160. /* 从相机位置到 windowPosition 处的像素创建射线在世界坐标系中 */
  161. var ray = this._viewer.scene.camera.getPickRay(screenPoint);
  162. /* 找到射线与渲染的地球表面之间的交点 */
  163. var position = this._viewer.scene.globe.pick(ray, this._viewer.scene);
  164. /* 获取地理位置的制图表达 */
  165. var cartographic = Cesium.Ellipsoid.WGS84.cartesianToCartographic(position);
  166. /* 查询屏幕位置的要素 */
  167. var feature = this._viewer.scene.pick(screenPoint);
  168. if (feature == undefined) {
  169. lng = this._arcToDegree(cartographic.longitude);
  170. lat = this._arcToDegree(cartographic.latitude);
  171. height = cartographic.height;
  172. } else {
  173. var cartesian = this._viewer.scene.pickPosition(screenPoint);
  174. if (Cesium.defined(cartesian)) {
  175. var cartographic = Cesium.Cartographic.fromCartesian(cartesian);
  176. lng = this._arcToDegree(cartographic.longitude);
  177. lat = this._arcToDegree(cartographic.latitude);
  178. height = cartographic.height;
  179. }
  180. }
  181. /* 返回结果 */
  182. return {
  183. lng: lng,
  184. lat: lat,
  185. height: height,
  186. }
  187. }
  188. /**
  189. * 屏幕位置转换为经纬度位置及空间位置
  190. * @ignore
  191. * @param {Cesium.Cartesian2} screenPosition 屏幕位置
  192. * @return {JSON} 经纬度位置及空间位置
  193. */
  194. _transfromFromScreenPoint(screenPosition) {
  195. /* 根据屏幕位置获取经度、纬度和高度信息 */
  196. let location = this._getScreenClickPositionAndHeight(screenPosition);
  197. /* 经纬度位置转换为三维坐标 */
  198. var cartesian = Cesium.Cartesian3.fromDegrees(location.lng, location.lat, location.height);
  199. /* 返回 */
  200. return {
  201. gLocation: location,
  202. sLocation: cartesian,
  203. }
  204. }
  205. }
  206. /**
  207. * 通用对外公开函数-鼠标事件
  208. */
  209. Object.assign(DrawPoint.prototype, /** @lends DrawPoint.prototype */ {
  210. /**
  211. * 设置鼠标为十字样式
  212. * @ignore 生成方法时不对外公开
  213. */
  214. _setMousePointerStyle() {
  215. document.querySelector('body').style.cursor = 'crosshair';
  216. },
  217. /**
  218. * 恢复鼠标指针为默认样式
  219. * @ignore 生成方法时不对外公开
  220. */
  221. _setMouseDefaultStyle() {
  222. document.querySelector('body').style.cursor = 'default';
  223. },
  224. /**
  225. * 注册鼠标左键点击事件
  226. * @ignore 生成方法时不对外公开
  227. * @param {Cesium.ScreenSpaceEventHandler} handler 事件句柄
  228. * @param {Function} callChange 回调callChange(event)
  229. */
  230. _registerLeftClickEvent(handler, callChange) {
  231. let _self = this;
  232. if (!handler) return;
  233. handler.setInputAction(function(event) {
  234. /* 锁定点击事件 以免和移动事件冲突 */
  235. _self._lock = true;
  236. clearTimeout(_self._timer);
  237. _self._timer = setTimeout(function() {
  238. if (callChange) callChange(event);
  239. /* 解除锁定 */
  240. _self._lock = false;
  241. }, 200);
  242. }, Cesium.ScreenSpaceEventType.LEFT_CLICK);
  243. },
  244. /**
  245. * 注册鼠标移动事件
  246. * @ignore 生成方法时不对外公开
  247. * @param {Cesium.ScreenSpaceEventHandler} handler 事件句柄
  248. * @param {Function} callChange 回调callChange(event)
  249. */
  250. _registerMouseMoveEvent(handler, callChange) {
  251. let _self = this;
  252. if (!handler) return;
  253. handler.setInputAction(function(event) {
  254. if (_self._lock === undefined || _self._lock === false) {
  255. if (callChange) callChange(event);
  256. }
  257. }, Cesium.ScreenSpaceEventType.MOUSE_MOVE);
  258. },
  259. /**
  260. * 注册鼠标左键按下事件
  261. * @ignore 生成方法时不对外公开
  262. * @param {Cesium.ScreenSpaceEventHandler} handler 事件句柄
  263. * @param {Function} callChange 回调callChange(event)
  264. */
  265. _registerLeftDownEvent(handler, callChange) {
  266. if (!handler) return;
  267. handler.setInputAction(function(event) {
  268. if (callChange) callChange(event);
  269. }, Cesium.ScreenSpaceEventType.LEFT_DOWN);
  270. },
  271. /**
  272. * 注册鼠标左键抬起事件
  273. * @ignore 生成方法时不对外公开
  274. * @param {Cesium.ScreenSpaceEventHandler} handler 事件句柄
  275. * @param {Function} callChange 回调callChange(event)
  276. */
  277. _registerLeftUpEvent(handler, callChange) {
  278. if (!handler) return;
  279. handler.setInputAction(function(event) {
  280. if (callChange) callChange(event);
  281. }, Cesium.ScreenSpaceEventType.LEFT_UP);
  282. },
  283. /**
  284. * 清除事件
  285. * @ignore
  286. * @param {Cesium.ScreenSpaceEventHandler} handler
  287. */
  288. _clearEvent(handler) {
  289. if (!handler) return;
  290. /* 干掉事件句柄 释放资源 */
  291. handler.destroy();
  292. handler = null;
  293. }
  294. });
  295. /**
  296. * 通用对外公开函数
  297. */
  298. Object.assign(DrawPoint.prototype, /** @lends DrawPoint.prototype */ {
  299. draw: function(type, options) {
  300. /* 定义自身 */
  301. let _self = this;
  302. /*撤销编辑*/
  303. _self._unActivateEdit();
  304. /* 注册事件 */
  305. this._drawEventHandler = new Cesium.ScreenSpaceEventHandler(this._viewer.scene.canvas);
  306. this._drawType = type;
  307. /* 分类型注册事件 */
  308. switch (type) {
  309. case DrawPoint.DrawType.Model: //模型
  310. _self._sketchDrawModel(_self._drawEventHandler, options);
  311. break;
  312. case DrawPoint.DrawType.Label: //文字
  313. _self._sketchDrawLabel(_self._drawEventHandler, options);
  314. break;
  315. case DrawPoint.DrawType.Point: //点
  316. _self._sketchDrawPoint(_self._drawEventHandler, options);
  317. break;
  318. case DrawPoint.DrawType.Point2Label: //点及文字
  319. _self._sketchDrawPoint2Label(_self._drawEventHandler, options);
  320. break;
  321. case DrawPoint.DrawType.Billboard: //广告牌
  322. _self._sketchDrawBillboard(_self._drawEventHandler, options);
  323. break;
  324. case DrawPoint.DrawType.Billboard2Label: //广告牌及文字
  325. _self._sketchDrawBillboard2Label(_self._drawEventHandler, options);
  326. break;
  327. }
  328. },
  329. /**
  330. * 清理所有资源
  331. */
  332. clearAll() {
  333. for (var i = 0; i < this._entities.length; i++) {
  334. var getById = viewer.entities.getById(this._entities[i]);
  335. if (getById) {
  336. this._viewer.entities.remove(getById);
  337. }
  338. }
  339. /* 关闭属性编辑框 */
  340. this._closePropertyEditDialog();
  341. },
  342. /**
  343. * 绘制文字工具
  344. * @ignore 生成方法时不对外公开
  345. * @param {Object} handler 事件句柄
  346. * @param {JSON} options 配置项
  347. * @param {Function} [options.onComplete(cPoint, gPoint)] 完成回调 可选
  348. * @param {Function} [options.onError(message)] 错误回到 可选
  349. */
  350. _sketchDrawLabel(handler, options) {
  351. let _self = this;
  352. /* 注册鼠标左键点击事件 */
  353. this._registerLeftClickEvent(handler, function(event) {
  354. /* 识别屏幕位置 */
  355. let loc = _self._transfromFromScreenPoint(event.position);
  356. if (!Cesium.defined(loc.sLocation)) return;
  357. let entityParam = DrawPoint.initEditPropertyParams();
  358. entityParam.label.font = entityParam.label.fontSize + "px " + entityParam.label.font;
  359. entityParam.label.pixelOffset = {
  360. x: entityParam.label.pixelOffsetX,
  361. y: entityParam.label.pixelOffsetY
  362. }
  363. /* 绘制文字 */
  364. _self._pointObject.addLabel(loc.sLocation, {
  365. label: entityParam.label
  366. }).then((entity) => {
  367. _self._entities.push(entity.id);
  368. entityParam = DrawPoint.initEditPropertyParams();
  369. _self._drawEntity = entity;
  370. /* 挂接参数到实体上 */
  371. _self._drawEntity.setParams(entityParam);
  372. /* 设置实体类型 */
  373. _self._drawEntity.setEntityType(DrawPoint.DrawType.Label);
  374. // 设置实体可编辑,编辑的实体必须包含编辑类型
  375. _self._setEntityIsEdit(_self._drawEntity);
  376. /* 干掉事件句柄 释放资源 */
  377. _self._clearEvent(handler);
  378. /* 监听输出 */
  379. if (options.onComplete) options.onComplete(loc.sLocation, loc.gLocation);
  380. });
  381. })
  382. },
  383. /**
  384. * 绘制点工具
  385. * @ignore 生成方法时不对外公开
  386. * @param {Object} handler 事件句柄
  387. * @param {JSON} options 配置项
  388. * @param {Function} [options.onComplete(cPoint, gPoint)] 完成回调 可选
  389. * @param {Function} [options.onError(message)] 错误回到 可选
  390. */
  391. _sketchDrawPoint(handler, options) {
  392. let _self = this;
  393. /* 注册鼠标左键点击事件 */
  394. this._registerLeftClickEvent(handler, function(event) {
  395. /* 识别屏幕位置 */
  396. let loc = _self._transfromFromScreenPoint(event.position);
  397. if (!Cesium.defined(loc.sLocation)) return;
  398. let entityParam = DrawPoint.initEditPropertyParams();
  399. /* 绘制文字 */
  400. _self._pointObject.addPoint(loc.sLocation, {
  401. point: entityParam.point
  402. }).then((entity) => {
  403. _self._entities.push(entity.id);
  404. entityParam = DrawPoint.initEditPropertyParams();
  405. _self._drawEntity = entity;
  406. /* 挂接参数到实体上 */
  407. _self._drawEntity.setParams(entityParam);
  408. /* 设置实体类型 */
  409. _self._drawEntity.setEntityType(DrawPoint.DrawType.Point);
  410. // 设置实体可编辑,编辑的实体必须包含编辑类型
  411. _self._setEntityIsEdit(_self._drawEntity);
  412. /* 干掉事件句柄 释放资源 */
  413. _self._clearEvent(handler);
  414. /* 监听输出 */
  415. if (options.onComplete) options.onComplete(loc.sLocation, loc.gLocation);
  416. });
  417. })
  418. },
  419. /**
  420. * 绘制点及文字工具
  421. * @ignore 生成方法时不对外公开
  422. * @param {Object} handler 事件句柄
  423. * @param {JSON} options 配置项
  424. * @param {Function} [options.onComplete(cPoint, gPoint)] 完成回调 可选
  425. * @param {Function} [options.onError(message)] 错误回到 可选
  426. */
  427. _sketchDrawPoint2Label(handler, options) {
  428. let _self = this;
  429. /* 注册鼠标左键点击事件 */
  430. this._registerLeftClickEvent(handler, function(event) {
  431. /* 识别屏幕位置 */
  432. let loc = _self._transfromFromScreenPoint(event.position);
  433. if (!Cesium.defined(loc.sLocation)) return;
  434. let entityParam = DrawPoint.initEditPropertyParams();
  435. entityParam.label.font = entityParam.label.fontSize + "px " + entityParam.label.font;
  436. entityParam.label.pixelOffset = {
  437. x: entityParam.label.pixelOffsetX,
  438. y: entityParam.label.pixelOffsetY - 10
  439. }
  440. /* 绘制文字 */
  441. _self._pointObject.addPoint(loc.sLocation, {
  442. point: entityParam.point,
  443. label: entityParam.label
  444. }).then((entity) => {
  445. _self._entities.push(entity.id);
  446. entityParam = DrawPoint.initEditPropertyParams();
  447. entityParam.label.pixelOffsetY = -10;
  448. _self._drawEntity = entity;
  449. /* 挂接参数到实体上 */
  450. _self._drawEntity.setParams(entityParam);
  451. /* 设置实体类型 */
  452. _self._drawEntity.setEntityType(DrawPoint.DrawType.Point2Label);
  453. // 设置实体可编辑,编辑的实体必须包含编辑类型
  454. _self._setEntityIsEdit(_self._drawEntity);
  455. /* 干掉事件句柄 释放资源 */
  456. _self._clearEvent(handler);
  457. /* 监听输出 */
  458. if (options.onComplete) options.onComplete(loc.sLocation, loc.gLocation);
  459. });
  460. })
  461. },
  462. /**
  463. * 绘制广告牌工具
  464. * @ignore 生成方法时不对外公开
  465. * @param {Object} handler 事件句柄
  466. * @param {JSON} options 配置项
  467. * @param {Function} [options.onComplete(cPoint, gPoint)] 完成回调 可选
  468. * @param {Function} [options.onError(message)] 错误回到 可选
  469. */
  470. _sketchDrawBillboard(handler, options) {
  471. let _self = this;
  472. /* 注册鼠标左键点击事件 */
  473. this._registerLeftClickEvent(handler, function(event) {
  474. /* 识别屏幕位置 */
  475. let loc = _self._transfromFromScreenPoint(event.position);
  476. if (!Cesium.defined(loc.sLocation)) return;
  477. let entityParam = DrawPoint.initEditPropertyParams();
  478. /* 绘制文字 */
  479. _self._pointObject.addBillboard(loc.sLocation, {
  480. billboard: entityParam.billboard
  481. }).then((entity) => {
  482. _self._entities.push(entity.id);
  483. entityParam = DrawPoint.initEditPropertyParams();
  484. entityParam.label.pixelOffsetY = -50;
  485. _self._drawEntity = entity;
  486. /* 挂接参数到实体上 */
  487. _self._drawEntity.setParams(entityParam);
  488. /* 设置实体类型 */
  489. _self._drawEntity.setEntityType(DrawPoint.DrawType.Billboard);
  490. // 设置实体可编辑,编辑的实体必须包含编辑类型
  491. _self._setEntityIsEdit(_self._drawEntity);
  492. /* 干掉事件句柄 释放资源 */
  493. _self._clearEvent(handler);
  494. /* 监听输出 */
  495. if (options.onComplete) options.onComplete(loc.sLocation, loc.gLocation);
  496. });
  497. })
  498. },
  499. /**
  500. * 绘制广告牌及文字工具
  501. * @ignore 生成方法时不对外公开
  502. * @param {Object} handler 事件句柄
  503. * @param {JSON} options 配置项
  504. * @param {Function} [options.onComplete(cPoint, gPoint)] 完成回调 可选
  505. * @param {Function} [options.onError(message)] 错误回到 可选
  506. */
  507. _sketchDrawBillboard2Label(handler, options) {
  508. let _self = this;
  509. /* 注册鼠标左键点击事件 */
  510. this._registerLeftClickEvent(handler, function(event) {
  511. /* 识别屏幕位置 */
  512. let loc = _self._transfromFromScreenPoint(event.position);
  513. if (!Cesium.defined(loc.sLocation)) return;
  514. let entityParam = DrawPoint.initEditPropertyParams();
  515. entityParam.label.font = entityParam.label.fontSize + "px " + entityParam.label.font;
  516. entityParam.label.pixelOffset = {
  517. x: entityParam.label.pixelOffsetX,
  518. y: entityParam.label.pixelOffsetY - 50
  519. }
  520. /* 绘制文字 */
  521. _self._pointObject.addBillboard(loc.sLocation, {
  522. billboard: entityParam.billboard,
  523. label: entityParam.label
  524. }).then((entity) => {
  525. _self._entities.push(entity.id);
  526. entityParam = DrawPoint.initEditPropertyParams();
  527. entityParam.label.pixelOffsetY = -50;
  528. _self._drawEntity = entity;
  529. /* 挂接参数到实体上 */
  530. _self._drawEntity.setParams(entityParam);
  531. /* 设置实体类型 */
  532. _self._drawEntity.setEntityType(DrawPoint.DrawType.Billboard2Label);
  533. // 设置实体可编辑,编辑的实体必须包含编辑类型
  534. _self._setEntityIsEdit(_self._drawEntity);
  535. /* 干掉事件句柄 释放资源 */
  536. _self._clearEvent(handler);
  537. /* 监听输出 */
  538. if (options.onComplete) options.onComplete(loc.sLocation, loc.gLocation);
  539. });
  540. })
  541. },
  542. /**
  543. * gltf
  544. * @ignore 生成方法时不对外公开
  545. * @param {Object} handler 事件句柄
  546. * @param {JSON} options 配置项
  547. * @param {Function} [options.onComplete(cPoint, gPoint)] 完成回调 可选
  548. * @param {Function} [options.onError(message)] 错误回到 可选
  549. */
  550. _sketchDrawModel(handler, options) {
  551. let _self = this;
  552. /* 注册鼠标左键点击事件 */
  553. this._registerLeftClickEvent(handler, function(event) {
  554. /* 识别屏幕位置 */
  555. let loc = _self._transfromFromScreenPoint(event.position);
  556. if (!Cesium.defined(loc.sLocation)) return;
  557. let entityParam = DrawPoint.initEditPropertyParams();
  558. /* 绘制文字 */
  559. _self._pointObject.addModel(loc.sLocation, {
  560. model: entityParam.model
  561. }).then((entity) => {
  562. _self._entities.push(entity.id);
  563. entityParam = DrawPoint.initEditPropertyParams();
  564. _self._drawEntity = entity;
  565. /* 挂接参数到实体上 */
  566. _self._drawEntity.setParams(entityParam);
  567. /* 设置实体类型 */
  568. _self._drawEntity.setEntityType(DrawPoint.DrawType.Model);
  569. // 设置实体可编辑,编辑的实体必须包含编辑类型
  570. _self._setEntityIsEdit(_self._drawEntity);
  571. /* 干掉事件句柄 释放资源 */
  572. _self._clearEvent(handler);
  573. /* 监听输出 */
  574. if (options.onComplete) options.onComplete(loc.sLocation, loc.gLocation);
  575. });
  576. })
  577. },
  578. /**
  579. * 更新当前编辑的实体属性
  580. * @param {JSON} params
  581. */
  582. updateEditEntityProperty: function(params) {
  583. let _self = this;
  584. if (this._editEntity === undefined) return;
  585. if (this._editEntity.getIsEdit() === undefined || this._editEntity.getIsEdit() === false) return;
  586. let editEntityType = this._editEntity.getEntityType();
  587. if (editEntityType === undefined) return;
  588. if (editEntityType === DrawPoint.DrawType.Label) {
  589. this._updateLabelProperty(params);
  590. } else if (editEntityType === DrawPoint.DrawType.Point) {
  591. this._updatePointProperty(params);
  592. } else if (editEntityType === DrawPoint.DrawType.Point2Label) {
  593. this._updatePoint2LabelProperty(params);
  594. } else if (editEntityType === DrawPoint.DrawType.Billboard) {
  595. this._updateBillboardProperty(params);
  596. } else if (editEntityType === DrawPoint.DrawType.Billboard2Label) {
  597. this._updateBillboard2LabelProperty(params);
  598. } else if (editEntityType === DrawPoint.DrawType.Model) {
  599. this._updateModelProperty(params);
  600. }
  601. },
  602. /**
  603. * 更新文字的属性
  604. * @ignore 不公开方法
  605. * @param {Object} params
  606. */
  607. _updateLabelProperty(params) {
  608. let label = params.label;
  609. this._editEntity.label.text=label.text;
  610. //组合字体
  611. // /*font:font-style font-weight font-size/line-height font-family;*/
  612. // font:italic bolder 20px/10px Arial;
  613. let font = "";
  614. if (label.italic) {
  615. font += 'italic '
  616. }
  617. if (label.bolder) {
  618. font += ' bolder '
  619. }
  620. font += label.fontSize + "px " + label.font;
  621. this._editEntity.label.font = font; //字体样式
  622. this._editEntity.label.fillColor = Cesium.Color.fromCssColorString(label.fillColor);
  623. this._editEntity.label.outlineColor = Cesium.Color.fromCssColorString(label.outlineColor);
  624. this._editEntity.label.outlineWidth = parseFloat(label.outlineWidth);
  625. this._editEntity.label.showBackground = label.showBackground;
  626. this._editEntity.label.backgroundColor = Cesium.Color.fromCssColorString(label.backgroundColor);
  627. this._editEntity.label.backgroundPadding = new Cesium.Cartesian2(parseFloat(label.backgroundPadding), parseFloat(label.backgroundPadding));
  628. this._editEntity.label.pixelOffset = new Cesium.Cartesian2(parseFloat(label.pixelOffsetX), parseFloat(label.pixelOffsetY));
  629. /* 重新关联实体的属性 */
  630. this._editEntity.setParams(params);
  631. },
  632. /**
  633. * 更新点的属性
  634. * @ignore 不公开方法
  635. * @param {Object} params
  636. */
  637. _updatePointProperty(params) {
  638. let point = params.point;
  639. this._editEntity.point.color = Cesium.Color.fromCssColorString(point.color);
  640. this._editEntity.point.pixelSize = parseFloat(point.pixelSize);
  641. this._editEntity.point.outlineColor = Cesium.Color.fromCssColorString(point.outlineColor);
  642. this._editEntity.point.outlineWidth = parseFloat(point.outlineWidth);
  643. /* 重新关联实体的属性 */
  644. this._editEntity.setParams(params);
  645. },
  646. /**
  647. * 更新点及文字的属性
  648. * @ignore 不公开方法
  649. * @param {Object} params
  650. */
  651. _updatePoint2LabelProperty(params) {
  652. let label = params.label;
  653. this._editEntity.label.text=label.text;
  654. let font = "";
  655. if (label.italic) {
  656. font += 'italic '
  657. }
  658. if (label.bolder) {
  659. font += ' bolder '
  660. }
  661. font += label.fontSize + "px " + label.font;
  662. this._editEntity.label.font = font; //字体样式
  663. this._editEntity.label.fillColor = Cesium.Color.fromCssColorString(label.fillColor);
  664. this._editEntity.label.outlineColor = Cesium.Color.fromCssColorString(label.outlineColor);
  665. this._editEntity.label.outlineWidth = parseFloat(label.outlineWidth);
  666. this._editEntity.label.showBackground = label.showBackground;
  667. this._editEntity.label.backgroundColor = Cesium.Color.fromCssColorString(label.backgroundColor);
  668. this._editEntity.label.backgroundPadding = new Cesium.Cartesian2(parseFloat(label.backgroundPadding), parseFloat(label.backgroundPadding));
  669. let point = params.point;
  670. this._editEntity.point.color = Cesium.Color.fromCssColorString(point.color);
  671. this._editEntity.point.pixelSize = parseFloat(point.pixelSize);
  672. this._editEntity.point.outlineColor = Cesium.Color.fromCssColorString(point.outlineColor);
  673. this._editEntity.point.outlineWidth = parseFloat(point.outlineWidth);
  674. /* 重新关联实体的属性 */
  675. this._editEntity.setParams(params);
  676. },
  677. /**
  678. * 更新广告牌的属性
  679. * @ignore 不公开方法
  680. * @param {Object} params
  681. */
  682. _updateBillboardProperty(params) {
  683. let billboard = params.billboard;
  684. this._editEntity.billboard.image = billboard.imgUrl;
  685. this._editEntity.billboard.scale = billboard.scale;
  686. /* 重新关联实体的属性 */
  687. this._editEntity.setParams(params);
  688. },
  689. /**
  690. * 更新广告牌及文字的属性
  691. * @ignore 不公开方法
  692. * @param {Object} params
  693. */
  694. _updateBillboard2LabelProperty(params) {
  695. let label = params.label;
  696. this._editEntity.label.text=label.text;
  697. let font = "";
  698. if (label.italic) {
  699. font += 'italic '
  700. }
  701. if (label.bolder) {
  702. font += ' bolder '
  703. }
  704. font += label.fontSize + "px " + label.font;
  705. this._editEntity.label.font = font; //字体样式
  706. this._editEntity.label.fillColor = Cesium.Color.fromCssColorString(label.fillColor);
  707. this._editEntity.label.outlineColor = Cesium.Color.fromCssColorString(label.outlineColor);
  708. this._editEntity.label.outlineWidth = parseFloat(label.outlineWidth);
  709. this._editEntity.label.showBackground = label.showBackground;
  710. this._editEntity.label.backgroundColor = Cesium.Color.fromCssColorString(label.backgroundColor);
  711. this._editEntity.label.backgroundPadding = new Cesium.Cartesian2(parseFloat(label.backgroundPadding), parseFloat(label.backgroundPadding));
  712. this._editEntity.label.pixelOffset = new Cesium.Cartesian2(parseFloat(label.pixelOffsetX), parseFloat(label.pixelOffsetY));
  713. let billboard = params.billboard;
  714. this._editEntity.billboard.image = billboard.imgUrl;
  715. this._editEntity.billboard.scale = billboard.scale;
  716. /* 重新关联实体的属性 */
  717. this._editEntity.setParams(params);
  718. },
  719. });
  720. /**
  721. * 属性编辑相关
  722. */
  723. Object.assign(DrawPoint.prototype, {
  724. /**
  725. * 设置实体可编辑,编辑的实体必须包含编辑类型
  726. * @ignore 生成方法时不对外公开
  727. * @param {Cesium.Entity} entity 编辑的实体
  728. */
  729. _setEntityIsEdit(entity) {
  730. let _self = this;
  731. /* 先撤销编辑 */
  732. this._unActivateEdit();
  733. /* 设置实体要素可编辑 */
  734. entity.setIsEdit(true);
  735. /* 激活编辑 并显示属性编辑框 */
  736. this._sendShowPropertyDialog(entity);
  737. /* 注册统一事件 用于单击拾取实体 */
  738. let handler = new Cesium.ScreenSpaceEventHandler(this._viewer.scene.canvas);
  739. this._registerLeftClickEvent(handler, function(event) {
  740. /* 只要点击 就清除选中状态 */
  741. _self._unActivateEdit();
  742. let feature = _self._viewer.scene.pick(event.position);
  743. if (feature !== undefined && feature.id instanceof Cesium.Entity) {
  744. let editEntityType = feature.id.getEntityType();
  745. if (editEntityType === DrawPoint.DrawType.Label ||
  746. editEntityType === DrawPoint.DrawType.Point ||
  747. editEntityType === DrawPoint.DrawType.Point2Label ||
  748. editEntityType === DrawPoint.DrawType.Billboard ||
  749. editEntityType === DrawPoint.DrawType.Billboard2Label ||
  750. editEntityType === DrawPoint.DrawType.Model) {
  751. feature.id.setIsEdit(true);
  752. _self._sendShowPropertyDialog(feature.id);
  753. }
  754. }
  755. });
  756. this._registerMouseMoveEvent(handler, function(event) {
  757. let toolTip = "单击修改属性,单击拖动修改位置";
  758. let feature = _self._viewer.scene.pick(event.endPosition);
  759. if (feature !== undefined && feature.id instanceof Cesium.Entity) {
  760. let editEntityType = feature.id.getEntityType();
  761. if (editEntityType === DrawPoint.DrawType.Label ||
  762. editEntityType === DrawPoint.DrawType.Point ||
  763. editEntityType === DrawPoint.DrawType.Point2Label ||
  764. editEntityType === DrawPoint.DrawType.Billboard ||
  765. editEntityType === DrawPoint.DrawType.Billboard2Label ||
  766. editEntityType === DrawPoint.DrawType.Model) {
  767. if (feature.id.getIsEdit()) {
  768. toolTip = "单击修改属性,单击拖动修改位置";
  769. CreateRemindertip(toolTip, event.endPosition, true);
  770. } else {
  771. toolTip = "单击修改属性";
  772. CreateRemindertip(toolTip, event.endPosition, true);
  773. }
  774. }
  775. } else {
  776. CreateRemindertip(toolTip, event.endPosition, false);
  777. }
  778. });
  779. },
  780. /**
  781. * 取消实体编辑激活状态
  782. * @ignore 生成方法时不对外公开
  783. */
  784. _unActivateEdit: function() {
  785. /* 清理事件句柄 */
  786. if (this._sketchEditHandler != undefined) {
  787. this._sketchEditHandler.removeInputAction(Cesium.ScreenSpaceEventType.LEFT_DOWN);
  788. this._sketchEditHandler.removeInputAction(Cesium.ScreenSpaceEventType.LEFT_UP);
  789. this._sketchEditHandler.removeInputAction(Cesium.ScreenSpaceEventType.MOUSE_MOVE);
  790. }
  791. this._editEntity = undefined;
  792. for (var i = 0; i < this._entities.length; i++) {
  793. var getById = this._viewer.entities.getById(this._entities[i]);
  794. if (getById) {
  795. getById.setIsEdit(false);
  796. }
  797. }
  798. /* 关闭属性编辑框 */
  799. this._closePropertyEditDialog();
  800. },
  801. /**
  802. * 打开实体编辑对话框
  803. * @ignore 生成方法时不对外公开
  804. * @param {Cesium.Entity} entity
  805. */
  806. _sendShowPropertyDialog(entity) {
  807. let _self = this;
  808. /* 获取可编辑实体的类型 */
  809. let editEntityType = entity.getEntityType();
  810. if (entity.getIsEdit() === undefined || entity.getIsEdit() === false || editEntityType === undefined) {
  811. /* 选择的实体不可编辑 */
  812. this._unActivateEdit();
  813. return;
  814. }
  815. /* 编辑属性 */
  816. let editProperty = entity.getParams();
  817. if (editProperty !== undefined && this.onEditProperty !== undefined) {
  818. editProperty.id = editEntityType;
  819. /* 更改测试 */
  820. _self._openPropertyEditDialog(editProperty,
  821. //编辑回调
  822. function(params) {
  823. _self.updateEditEntityProperty(params);
  824. },
  825. //移除回调
  826. function() {
  827. _self._viewer.entities.remove(entity);
  828. _self._editEntity = undefined;
  829. }
  830. );
  831. }
  832. this._activeteNormalEdit(entity);
  833. },
  834. /**
  835. * 激活编辑单实体
  836. * @ignore 生成方法时不对外公开
  837. * @param {Cesium.Entity} editEntity 编辑实体
  838. */
  839. _activeteNormalEdit: function(editEntity) {
  840. let _self = this;
  841. /* 获取编辑类型 */
  842. let entityType = editEntity.getEntityType();
  843. /* 赋值可编辑对象 */
  844. this._editEntity = editEntity;
  845. /* 创建事件句柄 */
  846. if (this._sketchEditHandler === undefined) {
  847. this._sketchEditHandler = new Cesium.ScreenSpaceEventHandler(this._viewer.scene.canvas);
  848. }
  849. /* 注册鼠标左键按下事件 */
  850. this._registerLeftDownEvent(this._sketchEditHandler, function(event) {
  851. const pickInfo = _self._viewer.scene.pick(event.position);
  852. console.log(pickInfo)
  853. if (!pickInfo) {
  854. return;
  855. }
  856. console.log("按下")
  857. // 如果点击空白区域,则不往下执行
  858. _self._viewer.scene.screenSpaceCameraController.enableRotate = false; // 将相机锁定,不然后续移动实体时相机也会动
  859. /* 注册鼠标移动事件 */
  860. _self._registerMouseMoveEvent(_self._sketchEditHandler, function(event) {
  861. console.log("移动")
  862. const position = event.endPosition; // event有startPosition与endPosition两个属性,即移动前后的位置信息:Cartesian2对象
  863. const cartesian = _self._viewer.scene.globe.pick(_self._viewer.camera.getPickRay(position), _self._viewer.scene); //将Cartesian2转为Cartesian3
  864. const selectedEntity = _self._editEntity; // 实体
  865. if (!selectedEntity) {
  866. return false;
  867. }
  868. //注意需要赋值三维坐标,// 更新实体位置为当前鼠标位置
  869. selectedEntity.position = cartesian;
  870. });
  871. /* 注册鼠标抬起事件 */
  872. _self._registerLeftUpEvent(_self._sketchEditHandler, function(event) {
  873. _self._sketchEditHandler.removeInputAction(Cesium.ScreenSpaceEventType.MOUSE_MOVE); // 解除viewer的MOUSE_MOVE事件监听器
  874. _self._sketchEditHandler.removeInputAction(Cesium.ScreenSpaceEventType.LEFT_UP); // 解除viewer的LEFT_UP事件监听器
  875. _self._viewer.scene.screenSpaceCameraController.enableRotate = true; // 取消相机锁定
  876. console.log("抬起")
  877. });
  878. });
  879. },
  880. /**
  881. * 更新模型的属性
  882. * @ignore 不公开方法
  883. * @param {Object} params
  884. */
  885. _updateModelProperty(params) {
  886. let model = params.model;
  887. this._editEntity.model.uri = model.url;
  888. this._editEntity.model.color = Cesium.Color.WHITE.withAlpha(model.alpha);
  889. this._editEntity.model.minimumPixelSize = model.minimumPixelSize;
  890. this._editEntity.model.maximumScale = model.maximumScale;
  891. this._editEntity.model.silhouetteSize = model.silhouetteSize;
  892. this._editEntity.model.silhouetteColor = new Cesium.Color.fromCssColorString(model.silhouetteColor);
  893. //弧度的航向分量。
  894. var heading = Cesium.Math.toRadians(model.heading);
  895. //弧度的螺距分量。
  896. var pitch = model.pitch;
  897. //滚动分量(以弧度为单位)
  898. var roll = model.roll;
  899. //HeadingPitchRoll旋转表示为航向,俯仰和滚动。围绕Z轴。节距是绕负y轴的旋转。滚动是关于正x轴。
  900. var hpr = new Cesium.HeadingPitchRoll(heading, pitch, roll);
  901. // this._editEntity.orientation = Cesium.Transforms.headingPitchRollQuaternion(this._editEntity.position, hpr); // 模型方向
  902. /* 重新关联实体的属性 */
  903. this._editEntity.setParams(params);
  904. },
  905. })
  906. /**
  907. * 属性编辑相关(UI)
  908. */
  909. Object.assign(DrawPoint.prototype, {
  910. /**
  911. * 打开属性编辑窗口
  912. * @ignore
  913. * @param {JSON} params 参数
  914. * @param {Function} callEdit 编辑回调
  915. * @param {Function} callRemove 移除回调
  916. */
  917. _openPropertyEditDialog: function(params, callEdit, callRemove) {
  918. this._editPropertyDialogDomId = 'dialog-property-dom-point';
  919. this._registerDOMPropertyEdit = 'dialog-edit-property-point';
  920. /* 获取一个属性编辑组件 */
  921. let PropertyEditComponent = customElements.get(this._registerDOMPropertyEdit);
  922. /* 如果组件还未注册 则进行注册 否则不在注册 避免重复注册的BUG */
  923. if (PropertyEditComponent === undefined) {
  924. PropertyEditComponent = defineCustomElement(DialogEditProperty);
  925. customElements.define(this._registerDOMPropertyEdit, PropertyEditComponent);
  926. }
  927. /* 先关闭编辑框 */
  928. this._closePropertyEditDialog();
  929. /* 创建组件 */
  930. let dialogPropertyElement = new PropertyEditComponent({
  931. params: params,
  932. })
  933. dialogPropertyElement.id = this._editPropertyDialogDomId;
  934. dialogPropertyElement.showDialog = true;
  935. document.body.appendChild(dialogPropertyElement);
  936. /* 监听修改事件 */
  937. dialogPropertyElement.addEventListener(
  938. "submit",
  939. (e) => {
  940. if (callEdit) callEdit(e.detail[0]);
  941. },
  942. false
  943. );
  944. /* 监听移除事件 */
  945. dialogPropertyElement.addEventListener(
  946. "remove",
  947. (e) => {
  948. if (callRemove) callRemove();
  949. },
  950. false
  951. );
  952. },
  953. /**
  954. * 关闭属性编辑框
  955. * @ignore
  956. */
  957. _closePropertyEditDialog() {
  958. let dom = document.getElementById(this._editPropertyDialogDomId);
  959. if (dom !== null && dom !== undefined) {
  960. document.body.removeChild(dom);
  961. }
  962. },
  963. })
  964. /**
  965. * 绘制类型
  966. */
  967. DrawPoint.DrawType = Object.freeze({
  968. Model: 'model', //模型
  969. Label: 'label', //文字
  970. Point: 'point', //点
  971. Point2Label: 'point2Label', //点及文字
  972. Billboard: 'billboard', //广告牌
  973. Billboard2Label: 'billboard2Label', //广告牌及文字
  974. })
  975. export default DrawPoint;