spatial-query3d.js 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424
  1. // 引入依赖
  2. import { watch, ref, reactive, toRefs, onBeforeUnmount, onMounted } from "vue";
  3. import tool from '../../../js/tool/tool.js' //提示等工具
  4. import resource from '../../../js/local/lang.js' //语言资源
  5. import { storeState, storeDate } from '../../../js/store/store.js' //简单局部状态管理
  6. import { initHandler, handlerDrawing, clearHandlerDrawing } from "../../../js/common/drawHandler.js" //公共handler.js
  7. import { Edit, clearEditHandler, } from "../../../js/common/editHandler.js" //公共handler.js
  8. import createTooltip from '../../../js/tool/tooltip2.js'
  9. function spatialQuery3d(props) {
  10. // 设置默认值数据
  11. let state = reactive({
  12. layerNames: [], //当前存在的可选择图层
  13. selectedLayerName: null, //默认选择图层名称
  14. scale: 3, //缩放
  15. positionMode: "intersects", //位置模式
  16. Xpitch: 0, //x旋转
  17. Yroll: 0, //y旋转
  18. Zheading: 0, //z旋转
  19. geometryType: "box", //选择模型类型
  20. drawType: "Fill_And_WireFrame", //模型显示类型
  21. FillColor: "rgba(192,211,25,0.5)", //模型填充颜色
  22. WireFrameColor: "rgba(89,129,228,0.8)", // 模型线框颜色
  23. searchColor: "rgba(255, 186, 1, 1)", //查询结果颜色
  24. GeometryBodyNames: [], //场景存在的天际线体对象等存在的数组
  25. //默认geometry参数
  26. boxParameters: [100, 100, 100],
  27. sphereParameters: [100],
  28. coneParameters: [100, 200],
  29. cylinderParameters: [100, 100, 200],
  30. ellicpseParameters: [100, 50, 50],
  31. rotateOrigin: null,
  32. });
  33. // 传入props改变默认值
  34. if (props) {
  35. for (let key in props) {
  36. if (state.hasOwnProperty(key)) {
  37. // 只在props[key]不为undefined时才覆盖默认值
  38. if (props[key] !== undefined) {
  39. state[key] = props[key];
  40. }
  41. } else {
  42. tool.Message.errorMsg(resource.AttributeError + key);
  43. }
  44. }
  45. }
  46. // 初始化数据
  47. let scene, tipFlag = true;
  48. let layers, spatialQuery;
  49. let geometry, GeometryBodys = [];
  50. let editEntity, s3mInstanceColc;
  51. let modelUrl = '/data/s3m/box.s3m';
  52. let modelEditor;
  53. if (storeState.isViewer) {
  54. if (!window.tooltip) {
  55. window.tooltip = createTooltip(viewer._element);
  56. }
  57. init();
  58. }
  59. //viewer 初始化完成的监听
  60. watch(() => storeState.isViewer, val => {
  61. if (val) {
  62. if (!window.tooltip) {
  63. window.tooltip = createTooltip(viewer._element);
  64. }
  65. init();
  66. }
  67. });
  68. //监听图层加载完成
  69. watch(() => storeState.changeLayers, val => {
  70. getLayerNames();
  71. });
  72. if (storeState.changeGeometrys) {
  73. setGeometryBodys()
  74. }
  75. //监听场景存在其他三维体
  76. watch(() => storeState.changeGeometrys, val => {
  77. setGeometryBodys()
  78. });
  79. function setGeometryBodys() {
  80. state.GeometryBodyNames = [];
  81. GeometryBodys = [];
  82. if (storeDate.geometrys) {
  83. for (const key in storeDate.geometrys) {
  84. GeometryBodys.push(key);
  85. let name = storeDate.geometrys[key].name;
  86. if (!state.GeometryBodyNames.includes(name)) {
  87. state.GeometryBodyNames.push(name)
  88. }
  89. }
  90. }
  91. if (state.GeometryBodyNames.length === 0) {
  92. if (props && props.geometryType) {
  93. state.geometryType = props.geometryType
  94. } else {
  95. state.geometryType = 'box'
  96. }
  97. }
  98. }
  99. function init() {
  100. scene = viewer.scene;
  101. layers = viewer.scene.layers.layerQueue;
  102. spatialQuery = new Cesium.SpatialQuery3D(scene);
  103. spatialQuery.outlineColor = Cesium.Color.fromCssColorString(
  104. state.WireFrameColor
  105. );
  106. spatialQuery.fillColor = Cesium.Color.fromCssColorString(
  107. state.FillColor
  108. );
  109. spatialQuery.fillStyle = Cesium.FillStyle[state.drawType];
  110. getGeometry(state.geometryType);
  111. getPositionMode(state.positionMode);
  112. spatialQuery.build();
  113. setTimeout(() => {
  114. if (state.layerNames.length === 0) {
  115. getLayerNames();
  116. }
  117. }, 1000);
  118. s3mInstanceColc = new Cesium.S3MInstanceCollection(scene._context);
  119. viewer.scene.primitives.add(s3mInstanceColc);
  120. };
  121. function getLayerNames() {
  122. let layer = getLayer(state.selectedLayerName);
  123. if (spatialQuery && spatialQuery.layers) {
  124. spatialQuery.layers = layer ? [layer] : []
  125. }
  126. state.layerNames.length = 0;
  127. if (layers && layers.length > 0) {
  128. layers.forEach((element, index) => {
  129. if (!state.layerNames.includes(element._name)) {
  130. state.layerNames.push(element._name);
  131. }
  132. });
  133. if (!state.selectedLayerName) {
  134. state.selectedLayerName = state.layerNames[0]
  135. }
  136. }
  137. }
  138. /*
  139. ***分析模块***
  140. */
  141. //分析
  142. function analysis() {
  143. try {
  144. let layer = getLayer(state.selectedLayerName);
  145. if (!layer) {
  146. tool.Message.warnMsg('请选择需要查询的图层!')
  147. return;
  148. }
  149. spatialQuery.layers = [layer];
  150. tooltip.setVisible(false);
  151. layer.selectedColor = Cesium.Color.fromCssColorString(state.searchColor);
  152. layer.selectColorType = Cesium.SelectColorType.REPLACE;
  153. layer.selectEnabled = false;
  154. console.log(spatialQuery.geometry)
  155. if (typeof (state.geometryType) === 'number') { //三维体查询,目前只支持这两种
  156. getGeometry(state.geometryType);
  157. spatialQuery.build();
  158. return;
  159. }
  160. spatialQuery.build();
  161. viewer.enableCursorStyle = false;
  162. viewer._element.style.cursor = "";
  163. document.body.classList.add("measureCur");
  164. if (tipFlag) { //只提示一次
  165. window.tooltip.showAt(' <p>点击鼠标左键确认查询位置</p>', '300px');
  166. tipFlag = false
  167. }
  168. //鼠标左键事件监听
  169. viewer.eventManager.addEventListener("CLICK", LEFT_CLICK, true);
  170. } catch (err) {
  171. console.error(err)
  172. }
  173. };
  174. function LEFT_CLICK(e) {
  175. document.body.classList.remove("measureCur");
  176. // 获取鼠标点击的笛卡尔坐标
  177. let cartesian = scene.pickPosition(e.message.position);
  178. let position = tool.CartesiantoDegrees(cartesian) // 将获取的点的位置转化成经纬度
  179. setPosition(position);
  180. // let h = position[2] + 60;
  181. // addModel(Cesium.Cartesian3.fromDegrees(position[0], position[1], h)); //添加编辑模型
  182. tooltip.setVisible(false);
  183. viewer.eventManager.removeEventListener("CLICK", LEFT_CLICK); //移除鼠标点击事件监听
  184. }
  185. function getLayer(layerName) {
  186. return layers.find(function (item, index) {
  187. return item._name === layerName
  188. })
  189. };
  190. function getQueryIDs() {
  191. return spatialQuery.getQueryIDs();
  192. };
  193. function getGeometry(geometryType) {
  194. switch (geometryType) {
  195. case "box":
  196. {
  197. let p = state.boxParameters;
  198. geometry = new Cesium.GeoBox(p[0], p[1], p[2]);
  199. }
  200. break;
  201. case "sphere":
  202. {
  203. let p = state.sphereParameters;
  204. geometry = new Cesium.GeoSphere(p[0]);
  205. }
  206. break;
  207. case "cone":
  208. {
  209. let p = state.coneParameters;
  210. geometry = new Cesium.GeoCone(p[0], p[1]);
  211. if (state.rotateOrigin) {
  212. geometry.rotateOrigin = getRotateOrigin();
  213. }
  214. }
  215. break;
  216. case "cylinder":
  217. {
  218. let p = state.cylinderParameters;
  219. geometry = new Cesium.GeoCylinder(p[0], p[1], p[2]);
  220. }
  221. break;
  222. case "ellicpse":
  223. {
  224. let p = state.ellicpseParameters;
  225. geometry = new Cesium.GeoEllipsoid(p[0], p[1], p[2]);
  226. }
  227. break;
  228. default:
  229. {
  230. geometry = new Cesium.GeoModel3D();
  231. geometry.geoModel = storeDate.geometrys['SkyLineBody'];
  232. spatialQuery.clear()
  233. }
  234. break;
  235. }
  236. spatialQuery.geometry = geometry;
  237. };
  238. //获取圆锥绕点旋转方式
  239. function getRotateOrigin() {
  240. let r = state.rotateOrigin;
  241. if (r == "APEX") {
  242. return Cesium.RotationOrigin.APEX;
  243. } else {
  244. return Cesium.RotationOrigin.CENTER;
  245. }
  246. };
  247. function getPositionMode(positionMode) {
  248. let mode;
  249. switch (positionMode) {
  250. case "intersects":
  251. mode = Cesium.PositionMode.Intersects;
  252. break;
  253. case "disjoint":
  254. mode = Cesium.PositionMode.Disjoint;
  255. break;
  256. case "contains":
  257. mode = Cesium.PositionMode.Contains;
  258. break;
  259. default:
  260. mode = Cesium.PositionMode.Intersects;
  261. break;
  262. }
  263. spatialQuery.positionMode = mode;
  264. };
  265. //设置查询中心点位置,可用于动态改变如机场预警范例
  266. function setPosition(newPosArr) {
  267. //传入经纬度数组
  268. if (spatialQuery && spatialQuery.geometry) {
  269. spatialQuery.geometry.geoPosition = new Cesium.Point3D(
  270. newPosArr[0],
  271. newPosArr[1],
  272. newPosArr[2]
  273. );
  274. }
  275. };
  276. function addModel(centerPositions) {
  277. s3mInstanceColc.add(modelUrl, {
  278. id: 'spatialQuery-model',
  279. position: centerPositions,
  280. // hpr: new Cesium.HeadingPitchRoll(heading, 0, 0),
  281. // color:Cesium.Color.RED,
  282. scale: new Cesium.Cartesian3(0.1, 0.1, 0.1),
  283. });
  284. editEntity = s3mInstanceColc.getInstance(modelUrl, 'spatialQuery-model');
  285. if (!modelEditor) addModelEditor(editEntity);
  286. else {
  287. modelEditor.setEditObject(editEntity);
  288. modelEditor.activate();
  289. }
  290. }
  291. function addModelEditor(model) {
  292. modelEditor = new Cesium.ModelEditor({
  293. model: model,
  294. scene: viewer.scene,
  295. axesShow: {
  296. "translation": true,
  297. "rotation": true,
  298. "scale": false
  299. }
  300. });
  301. modelEditor.activate();
  302. modelEditor.changedEvt.addEventListener((param) => {
  303. console.log(param)
  304. let Cartesian3 = new Cesium.Cartesian3();
  305. Cesium.Matrix4.getTranslation(param.modelMatrix, Cartesian3);
  306. if (Cartesian3) {
  307. }
  308. })
  309. }
  310. // 清除
  311. function clear() {
  312. let layer = getLayer(state.selectedLayerName);
  313. console.log(layer)
  314. if (layer) {
  315. layer.selectedColor = new Cesium.Color(0.7, 0.7, 1, 1);
  316. layer.setSelection([]);
  317. layer.selectColorType = Cesium.SelectColorType.MIX;
  318. }
  319. spatialQuery.clear();
  320. tooltip.setVisible(false);
  321. document.body.classList.remove("measureCur");
  322. spatialQuery.geometry.geoPosition = new Cesium.Point3D(0, 0, 0);
  323. viewer.eventManager.removeEventListener("CLICK", LEFT_CLICK); //移除鼠标点击事件监听
  324. };
  325. // 监听
  326. watch(() => state.Xpitch, val => {
  327. if (val == "") return;
  328. geometry.geoRotationX = parseFloat(val);
  329. });
  330. watch(() => state.Yroll, val => {
  331. if (val == "") return;
  332. geometry.geoRotationY = parseFloat(val);
  333. });
  334. watch(() => state.Zheading, val => {
  335. if (val == "") return;
  336. geometry.geoRotationZ = parseFloat(val);
  337. });
  338. watch(() => state.scale, val => {
  339. if (val == "") return;
  340. geometry.geoScaleX = parseFloat(val);
  341. geometry.geoScaleY = parseFloat(val);
  342. geometry.geoScaleZ = parseFloat(val);
  343. });
  344. watch(() => state.positionMode, val => {
  345. if (val == "") return;
  346. getPositionMode(val)
  347. });
  348. watch(() => state.geometryType, val => {
  349. if (val === "") return;
  350. getGeometry(val)
  351. });
  352. watch(() => state.drawType, val => {
  353. if (val == "") return;
  354. spatialQuery.fillStyle = Cesium.FillStyle[val];
  355. });
  356. watch(() => state.FillColor, val => {
  357. if (val == "") return;
  358. spatialQuery.fillColor = Cesium.Color.fromCssColorString(val);
  359. });
  360. watch(() => state.WireFrameColor, val => {
  361. if (val == "") return;
  362. spatialQuery.outlineColor = Cesium.Color.fromCssColorString(val);
  363. });
  364. watch(() => state.searchColor, val => {
  365. if (val == "") return;
  366. getLayer(state.selectedLayerName).selectedColor = Cesium.Color.fromCssColorString(val);
  367. });
  368. watch(() => state.selectedLayerName, (val, oldval) => {
  369. let layer = getLayer(oldval);
  370. if (layer) {
  371. layer.selectedColor = new Cesium.Color(0.7, 0.7, 1, 1);
  372. layer.setSelection([]);
  373. layer.selectColorType = Cesium.SelectColorType.MIX;
  374. }
  375. clear()
  376. });
  377. // 销毁
  378. onBeforeUnmount(() => {
  379. spatialQuery.destroy();
  380. spatialQuery = undefined;
  381. layers = undefined;
  382. geometry = undefined;
  383. })
  384. return {
  385. ...toRefs(state),
  386. setPosition,
  387. getQueryIDs,
  388. analysis,
  389. clear
  390. };
  391. };
  392. export default spatialQuery3d