hcxx.vue 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493
  1. <template>
  2. <div>
  3. <div class="detailList">
  4. <el-descriptions :column="1" border>
  5. <el-descriptions-item
  6. label="图斑编号"
  7. label-class-name="my-label"
  8. content-class-name="my-content"
  9. >{{ hcObj.jcbh || "无" }}</el-descriptions-item
  10. >
  11. <el-descriptions-item
  12. label="外业核实情况"
  13. content-class-name="my-content"
  14. :span="3"
  15. >{{ hcObj.wyhsqk || "无" }}</el-descriptions-item
  16. >
  17. <el-descriptions-item label="实际地类代码">{{
  18. hcObj.sjdldm || "无"
  19. }}</el-descriptions-item>
  20. <el-descriptions-item label="调查人员">{{
  21. hcObj.dcry || "无"
  22. }}</el-descriptions-item>
  23. <el-descriptions-item label="调查时间">{{
  24. hcObj.dcsj || "无"
  25. }}</el-descriptions-item>
  26. <el-descriptions-item label="外业预判">
  27. {{ hcObj.wyyp || "无" }}
  28. </el-descriptions-item>
  29. <el-descriptions-item label="核查结果">
  30. {{ hcObj.hcjg || "无" }}
  31. </el-descriptions-item>
  32. </el-descriptions>
  33. </div>
  34. <div class="imgCon">
  35. <div class="echartTitle">
  36. <div class="block-title">现场照片</div>
  37. </div>
  38. <div class="imgList">
  39. <div
  40. class="imgDiv"
  41. :class="{ hiimg: hiindex === i }"
  42. v-for="(item, i) in monitorList"
  43. :key="i"
  44. @click="clickImg(i)"
  45. @mouseenter="handleMouseEnter(item, i)"
  46. @mouseleave="handleMouseLeave(item, i)"
  47. >
  48. <span>{{ i + 1 }}</span>
  49. <!-- <img :src="imgUrl" /> -->
  50. <img :src="item.imagerPath" />
  51. <!-- <img :src="imgUrl + item.imagerPath" /> -->
  52. <p>{{ item.imagerSj }}</p>
  53. </div>
  54. </div>
  55. </div>
  56. <div class="imgCon">
  57. <div class="echartTitle">
  58. <div class="block-title">无人机取证</div>
  59. </div>
  60. <div class="imgList">
  61. <div
  62. class="imgDiv"
  63. v-for="(item, i) in xsxList"
  64. :key="i"
  65. @click="clickxsx(item)"
  66. >
  67. <span>{{ i + 1 }}</span>
  68. <img :src="item.imagerPath" />
  69. </div>
  70. </div>
  71. </div>
  72. </div>
  73. </template>
  74. <script>
  75. import { getJctbhcInfo, getTiffPath } from "@/api/ghss/jctb.js";
  76. import { loadGeoJSON } from "@/utils/MapHelper/help.js";
  77. export default {
  78. props: {
  79. detailObj: {
  80. type: Object,
  81. },
  82. jcbh: {
  83. type: String,
  84. },
  85. },
  86. components: {},
  87. data() {
  88. return {
  89. imgUrl: "",
  90. monitorList: [],
  91. primitive: null,
  92. selectId: null,
  93. primitivesArray: [],
  94. hcObj: {},
  95. // jtArr:[],//箭头id数组
  96. // dwArr:[],//
  97. idArr: [], //id数组
  98. handler: {},
  99. hiindex: "",
  100. hiid: "",
  101. xsxList: [],
  102. };
  103. },
  104. computed: {},
  105. mounted() {
  106. this.$nextTick(() => {
  107. this.inputAction();
  108. });
  109. },
  110. methods: {
  111. inputAction() {
  112. // 为viewer添加鼠标移动的监听事件
  113. // viewer.screenSpaceEventHandler.setInputAction(function (movement) {
  114. // // movement.endPosition是一个Cesium.Cartesian2对象,表示鼠标在屏幕上的位置
  115. // }, Cesium.ScreenSpaceEventType.MOUSE_MOVE);
  116. this.handler = new Cesium.ScreenSpaceEventHandler(viewer.scene.canvas);
  117. // this.handler.setInputAction(function (movement) {
  118. // let pickedFeature = scene.pick(movement.position);
  119. // console.log(movement,pickedFeature,'////');
  120. // // that[queryName](movement);
  121. // }, Cesium.ScreenSpaceEventType.MOUSE_MOVE);
  122. // 鼠标移动事件
  123. this.handler.setInputAction((event) => {
  124. if (this.hiid) {
  125. this.handleMouseLeave({ id: this.hiid });
  126. }
  127. let pickObj = viewer.scene.pick(event.endPosition);
  128. if (Cesium.defined(pickObj)) {
  129. if (pickObj.id && pickObj.id.id.includes("jt")) {
  130. this.hiid = pickObj.id.id.replace("jt", "");
  131. this.handleMouseEnter({ id: this.hiid });
  132. this.hiindex = this.idArr.indexOf(this.hiid);
  133. this.clickImg(this.hiindex);
  134. }
  135. }
  136. }, Cesium.ScreenSpaceEventType.MOUSE_MOVE);
  137. },
  138. handleMouseEnter(a, b) {
  139. this.ceshi(a.id, "yr");
  140. },
  141. handleMouseLeave(a, b) {
  142. this.ceshi(a.id, "yc");
  143. },
  144. changeData(name, updata) {
  145. this[name] = updata;
  146. },
  147. clickImg(val) {
  148. this.$emit("updateParent", "emitImgList", this.monitorList);
  149. this.$emit("updateParent", "emitImgIndex", val);
  150. },
  151. //getEntities(id, url, position, type) {
  152. clickxsx(item) {
  153. let posArr = item.pngenvelope;
  154. // 创建Cesium的ImageMaterialProperty
  155. const imageMaterial = new Cesium.ImageMaterialProperty({
  156. image: item.imagerPath,
  157. repeat: new Cesium.Cartesian2(1.0, 1.0), // 控制图像重复,这里设置为不重复
  158. transparent: true, // 如果图像有透明通道,设置为true
  159. });
  160. loadGeoJSON(this.detailObj.geom, "#ff0000", { isfly: true }, (data) => {
  161. data.entities.add({
  162. name: "Image Overlay",
  163. id: "wrj",
  164. rectangle: {
  165. coordinates: Cesium.Rectangle.fromDegrees(
  166. posArr[0],
  167. posArr[1],
  168. posArr[2],
  169. posArr[3]
  170. ), // 设置矩形的经纬度范围
  171. material: imageMaterial,
  172. },
  173. });
  174. layerSources["wrj"] = data;
  175. });
  176. },
  177. // aaa() {
  178. // var redLine = viewer.entities.add({
  179. // // 贴在地面上 两点之间的直线距离
  180. // name: "line",
  181. // polyline: {
  182. // positions: Cesium.Cartesian3.fromDegreesArray([
  183. // // o.inx,
  184. // // o.iny,
  185. // // o.outx,
  186. // // o.outy,
  187. // 109.5077, 18.309, 109.5111, 18.3093,
  188. // ]),
  189. // width: 20,
  190. // // 不带箭头的线
  191. // // material: Cesium.Color.RED,
  192. // // 是否紧贴地面
  193. // clampToGround: true,
  194. // // 带箭头的线
  195. // material: new Cesium.PolylineArrowMaterialProperty(Cesium.Color.RED),
  196. // },
  197. // });
  198. // },
  199. //加载图片
  200. ddd(obj) {
  201. // 将经纬度转换为 Cartesian3 坐标,起始点
  202. //起始点
  203. var startPosition = Cesium.Cartesian3.fromDegrees(
  204. Number(obj.imagerLzb),
  205. Number(obj.imagerBzb)
  206. );
  207. let poi = this.getLonAndLat(
  208. Number(obj.imagerLzb),
  209. Number(obj.imagerBzb),
  210. Number(obj.imagerAngle),
  211. 20
  212. );
  213. //结束点
  214. var targetPosition = Cesium.Cartesian3.fromDegrees(poi.lng, poi.lat);
  215. // 创建一个实体来表示点
  216. var pointEntity = viewer.entities.add({
  217. id: "dw" + obj.id,
  218. position: startPosition, // 点的位置
  219. point: {
  220. heightReference: Cesium.HeightReference.CLAMP_TO_GROUND, // 设置为贴地
  221. pixelSize: 10, // 点的大小
  222. color: Cesium.Color.RED, // 点的颜色
  223. outlineColor: Cesium.Color.BLACK, // 点的轮廓颜色
  224. outlineWidth: 2, // 点的轮廓宽度
  225. },
  226. });
  227. // 创建一个实体来放置箭头
  228. var arrowEntity = viewer.entities.add({
  229. id: "jt" + obj.id,
  230. position: startPosition, // 设置箭头位置
  231. billboard: {
  232. // image: "http://192.168.176.1:8001/长箭头.png", // 设置箭头图标
  233. image: "/static/images/路径@3x-2.png", // 设置箭头图标
  234. width: 37, // 设置图标宽度
  235. height: 69, // 设置图标高度
  236. scale: 0.7, // 设置图标缩放
  237. rotation: Cesium.Math.toRadians(360 - Number(obj.imagerAngle)), // 可选,默认为0
  238. // rotation: Number(obj.imagerAngle), // 可选,默认为0
  239. heightReference: Cesium.HeightReference.CLAMP_TO_GROUND, // 设置贴地
  240. },
  241. });
  242. // // 计算箭头的方向并更新
  243. // function updateArrowOrientation() {
  244. // // 计算起点到目标点的方向向量
  245. // var direction = Cesium.Cartesian3.subtract(
  246. // targetPosition,
  247. // startPosition,
  248. // new Cesium.Cartesian3()
  249. // );
  250. // // 确保方向向量有效
  251. // if (Cesium.Cartesian3.magnitude(direction) > 0) {
  252. // // 计算箭头朝向目标的方向角(使用 JavaScript 原生 Math.atan2)
  253. // var heading = Cesium.Math.toDegrees(
  254. // Math.atan2(direction.y, direction.x)
  255. // );
  256. // // 固定方向,使用 rotation 设置固定旋转
  257. // arrowEntity.billboard.rotation = Cesium.Math.toRadians(heading); // 固定旋转角度,不随地图旋转
  258. // }
  259. // }
  260. // // 每次视图更新时,重新计算箭头方向
  261. // viewer.scene.preRender.addEventListener(function () {
  262. // updateArrowOrientation();
  263. // });
  264. // 聚焦视角到箭头位置
  265. // viewer.zoomTo(arrowEntity);
  266. },
  267. ceshi(id, evtName) {
  268. let aaa = viewer.entities.getById("jt" + id);
  269. if (evtName == "yr") {
  270. aaa.billboard.image = "/static/images/路径@3x.png";
  271. } else {
  272. aaa.billboard.image = "/static/images/路径@3x-2.png";
  273. }
  274. },
  275. /**
  276. * 根据一个经纬度及距离角度,算出另外一个经纬度
  277. * @param {*} lng 经度 113.3960698
  278. * @param {*} lat 纬度 22.941386
  279. * @param {*} brng 方位角 45 ---- 正北方:000°或360° 正东方:090° 正南方:180° 正西方:270°
  280. * @param {*} dist 90000距离(米)
  281. * 1、角度转换为弧度公式:弧度=角度×(π ÷度180 )
  282. * 2、弧度转换为角度公式: 角度=弧度×(180÷π)
  283. */
  284. getLonAndLat(lng, lat, brng, dist) {
  285. //大地坐标系资料WGS-84 长半径a=6378137 短半径b=6356752.3142 扁率f=1/298.2572236
  286. var a = 6378137;
  287. var b = 6356752.3142;
  288. var f = 1 / 298.257223563;
  289. var lon1 = lng * 1;
  290. var lat1 = lat * 1;
  291. var s = dist;
  292. var alpha1 = brng * (Math.PI / 180); //mapNumberUtil.rad(brng);
  293. var sinAlpha1 = Math.sin(alpha1);
  294. var cosAlpha1 = Math.cos(alpha1);
  295. //var tanU1 = (1 - f) * Math.tan(mapNumberUtil.rad(lat1));
  296. var tanU1 = (1 - f) * Math.tan(lat1 * (Math.PI / 180));
  297. var cosU1 = 1 / Math.sqrt(1 + tanU1 * tanU1),
  298. sinU1 = tanU1 * cosU1;
  299. var sigma1 = Math.atan2(tanU1, cosAlpha1);
  300. var sinAlpha = cosU1 * sinAlpha1;
  301. var cosSqAlpha = 1 - sinAlpha * sinAlpha;
  302. var uSq = (cosSqAlpha * (a * a - b * b)) / (b * b);
  303. var A =
  304. 1 + (uSq / 16384) * (4096 + uSq * (-768 + uSq * (320 - 175 * uSq)));
  305. var B = (uSq / 1024) * (256 + uSq * (-128 + uSq * (74 - 47 * uSq)));
  306. var sigma = s / (b * A),
  307. sigmaP = 2 * Math.PI;
  308. while (Math.abs(sigma - sigmaP) > 1e-12) {
  309. var cos2SigmaM = Math.cos(2 * sigma1 + sigma);
  310. var sinSigma = Math.sin(sigma);
  311. var cosSigma = Math.cos(sigma);
  312. var deltaSigma =
  313. B *
  314. sinSigma *
  315. (cos2SigmaM +
  316. (B / 4) *
  317. (cosSigma * (-1 + 2 * cos2SigmaM * cos2SigmaM) -
  318. (B / 6) *
  319. cos2SigmaM *
  320. (-3 + 4 * sinSigma * sinSigma) *
  321. (-3 + 4 * cos2SigmaM * cos2SigmaM)));
  322. sigmaP = sigma;
  323. sigma = s / (b * A) + deltaSigma;
  324. }
  325. var tmp = sinU1 * sinSigma - cosU1 * cosSigma * cosAlpha1;
  326. var lat2 = Math.atan2(
  327. sinU1 * cosSigma + cosU1 * sinSigma * cosAlpha1,
  328. (1 - f) * Math.sqrt(sinAlpha * sinAlpha + tmp * tmp)
  329. );
  330. var lambda = Math.atan2(
  331. sinSigma * sinAlpha1,
  332. cosU1 * cosSigma - sinU1 * sinSigma * cosAlpha1
  333. );
  334. var C = (f / 16) * cosSqAlpha * (4 + f * (4 - 3 * cosSqAlpha));
  335. var L =
  336. lambda -
  337. (1 - C) *
  338. f *
  339. sinAlpha *
  340. (sigma +
  341. C *
  342. sinSigma *
  343. (cos2SigmaM + C * cosSigma * (-1 + 2 * cos2SigmaM * cos2SigmaM)));
  344. var revAz = Math.atan2(sinAlpha, -tmp); // final bearing
  345. var lngLatObj = {
  346. lng: lon1 + L * (180 / Math.PI),
  347. lat: lat2 * (180 / Math.PI),
  348. };
  349. return lngLatObj;
  350. },
  351. delatePoi(type) {
  352. if (this.idArr.length != 0) {
  353. this.idArr.forEach((item) => {
  354. viewer.entities.removeById(type + item);
  355. });
  356. // this.idArr = [];
  357. }
  358. },
  359. },
  360. watch: {
  361. jcbh: {
  362. handler(newVal, oldVal) {
  363. getJctbhcInfo(newVal).then((res) => {
  364. this.idArr = [];
  365. if (res.code == 200) {
  366. this.monitorList = res.data.images;
  367. this.hcObj = res.data;
  368. this.monitorList.forEach((item, i) => {
  369. item.name = res.data.dcry;
  370. item.imagerPath =
  371. window.axiosURI + "/file/upload/attachment" + item.imagerPath;
  372. this.ddd(item);
  373. this.idArr.push(item.id);
  374. });
  375. }
  376. });
  377. },
  378. deep: true,
  379. immediate: true,
  380. },
  381. detailObj: {
  382. handler(newVal, oldVal) {
  383. if (newVal.xsxtif) {
  384. this.xsxList = [];
  385. getTiffPath(this.detailObj.xsxtif).then((res) => {
  386. if (res.data.pngenvelope) {
  387. this.xsxList = [
  388. {
  389. imagerPath:
  390. window.axiosURI +
  391. "/file/upload/attachment" +
  392. res.data.pngpath,
  393. pngenvelope: res.data.pngenvelope,
  394. },
  395. ];
  396. }
  397. });
  398. }
  399. },
  400. deep: true,
  401. immediate: true,
  402. },
  403. },
  404. beforeDestroy() {
  405. this.delatePoi("jt");
  406. this.delatePoi("dw");
  407. this.handler.destroy();
  408. this.handler = null;
  409. viewer.dataSources.remove(layerSources["wrj"]);
  410. },
  411. };
  412. </script>
  413. <style lang="less" scoped>
  414. /deep/ .el-descriptions-item__label.is-bordered-label {
  415. color: #fff;
  416. background-color: transparent;
  417. }
  418. /deep/ .el-descriptions__body {
  419. color: #fff;
  420. background-color: transparent;
  421. }
  422. .imgCon {
  423. .imgList {
  424. width: 100%;
  425. // height: 300px;
  426. max-height: 400px;
  427. display: flex;
  428. flex-wrap: wrap;
  429. // background-color: rgba(255, 192, 203, 0.372);
  430. .imgDiv {
  431. width: 126px;
  432. height: 83px;
  433. margin-right: 10px;
  434. // background-color: rgba(0, 255, 255, 0.413);
  435. position: relative;
  436. margin: 4px 4px;
  437. img {
  438. width: 126px;
  439. height: 83px;
  440. }
  441. span {
  442. width: 26px;
  443. height: 26px;
  444. display: inline-block;
  445. position: absolute;
  446. top: 0;
  447. left: 0;
  448. background: #dbad70;
  449. text-align: center;
  450. line-height: 26px;
  451. }
  452. p {
  453. position: absolute;
  454. bottom: 0;
  455. font-size: 10px;
  456. color: #33ccff;
  457. text-align: center;
  458. width: 100%;
  459. height: 30px;
  460. line-height: 30px;
  461. }
  462. }
  463. .hiimg {
  464. border: 1px solid red;
  465. }
  466. }
  467. }
  468. .detailList {
  469. margin-top: 10px;
  470. }
  471. /deep/ .el-descriptions .is-bordered .el-descriptions-item__cell {
  472. padding: 3px;
  473. }
  474. </style>