工具
This commit is contained in:
		
							
								
								
									
										4
									
								
								src/renderer/src/icons/svg/turn.svg
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										4
									
								
								src/renderer/src/icons/svg/turn.svg
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,4 @@
 | 
			
		||||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="12" height="12" viewBox="0 0 12 12" fill="none">
 | 
			
		||||
<path d="M3.06995 0.0336822C3.30345 -0.0134909 3.72175 0.0203715 4.04432 0.0203715L8.80938 0.0203715C9.40915 0.0203715 10.1307 -0.0457695 10.6647 0.0603036C11.1902 0.1647 11.5443 0.463472 11.7725 0.858946C12.0226 1.29218 11.9994 1.8259 11.9994 2.52278L11.9994 10.1232C11.9994 11.3662 11.3459 12 10.0774 12L3.41699 12C3.05145 12 2.7978 11.9615 2.78966 11.6805C2.77859 11.2992 3.13767 11.3345 3.59051 11.3345L9.62358 11.3345C9.9666 11.3345 10.3532 11.3732 10.5979 11.3078C10.9435 11.2156 11.2516 10.9028 11.3187 10.5225C11.3785 10.1841 11.3321 9.80816 11.3321 9.41772L11.3321 2.70913C11.3321 2.34708 11.3626 1.95707 11.3321 1.59103C11.2915 1.1051 10.9141 0.772719 10.5312 0.699218C10.2419 0.643685 9.88335 0.685907 9.54349 0.685907L3.55046 0.685907C3.25907 0.685907 2.87412 0.72524 2.803 0.446314C2.74999 0.238375 2.86113 0.0758638 3.06995 0.0336822ZM4.9653 7.34125L2.00215 7.34125C1.65943 7.34125 1.32269 7.37425 1.04113 7.31463C0.477442 7.19527 0.00413877 6.69706 2.77496e-05 6.02349C-0.00437695 5.30309 0.516243 4.73537 1.24135 4.67911C1.82735 4.63364 2.47369 4.67911 3.11 4.67911L4.9653 4.67911C5.01246 4.16292 4.79863 2.94146 5.29899 2.94872C5.53703 2.95217 5.7177 3.11918 5.87293 3.24155C6.7027 3.89572 7.45568 4.47287 8.31552 5.11836C8.57959 5.3166 9.11366 5.62915 9.10303 6.05011C9.09247 6.46816 8.55953 6.78468 8.30218 6.98186C7.46283 7.62495 6.69288 8.19646 5.84623 8.83205C5.69609 8.94478 5.46648 9.11088 5.2456 9.05833C4.76802 8.9447 5.0393 7.88096 4.9653 7.34125Z"   fill="#FFFFFF" >
 | 
			
		||||
</path>
 | 
			
		||||
</svg>
 | 
			
		||||
| 
		 After Width: | Height: | Size: 1.6 KiB  | 
							
								
								
									
										138
									
								
								src/renderer/src/utils/HighDefinitionScreenshot.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										138
									
								
								src/renderer/src/utils/HighDefinitionScreenshot.ts
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,138 @@
 | 
			
		||||
export function processBase64Images(base64Data1, base64Data2, callback) {
 | 
			
		||||
  if (!base64Data1 || !base64Data2) {
 | 
			
		||||
    alert("请输入两个Base64图像数据");
 | 
			
		||||
    return;
 | 
			
		||||
  }
 | 
			
		||||
  // 创建Image对象并加载第一个Base64图像
 | 
			
		||||
  const img1 = new Image();
 | 
			
		||||
  img1.onload = function () {
 | 
			
		||||
    // 创建Image对象并加载第二个Base64图像
 | 
			
		||||
    const img2 = new Image();
 | 
			
		||||
    img2.onload = function () {
 | 
			
		||||
      // 计算拼接后的Canvas尺寸(这里示例为水平拼接,垂直拼接可调整计算方式)
 | 
			
		||||
      const totalWidth = img1.width + img2.width;
 | 
			
		||||
      const maxHeight = Math.max(img1.height, img2.height);
 | 
			
		||||
      console.log("maxHeight", maxHeight);
 | 
			
		||||
      const resultCanvas = document.createElement("canvas");
 | 
			
		||||
      // 设置结果Canvas的尺寸
 | 
			
		||||
      resultCanvas.width = totalWidth;
 | 
			
		||||
      resultCanvas.height = maxHeight;
 | 
			
		||||
 | 
			
		||||
      // 获取Canvas绘图上下文
 | 
			
		||||
      const ctx = resultCanvas.getContext("2d");
 | 
			
		||||
 | 
			
		||||
      // 绘制第一个图像(左上角开始)
 | 
			
		||||
      ctx.drawImage(img1, 0, 0);
 | 
			
		||||
 | 
			
		||||
      // 绘制第二个图像(第一个图像右侧)
 | 
			
		||||
      ctx.drawImage(img2, img1.width, 0);
 | 
			
		||||
 | 
			
		||||
      // 获取拼接后的Base64结果(默认为PNG格式,可指定其他格式如JPEG)
 | 
			
		||||
      const resultBase64Data = resultCanvas.toDataURL("image/png");
 | 
			
		||||
      callback(resultBase64Data);
 | 
			
		||||
      console.log("图像拼接完成,Base64结果已生成");
 | 
			
		||||
    };
 | 
			
		||||
    img2.src = base64Data1;
 | 
			
		||||
  };
 | 
			
		||||
  img1.src = base64Data2;
 | 
			
		||||
}
 | 
			
		||||
/**
 | 
			
		||||
 * 拼接两个Base64图像并返回新的Base64
 | 
			
		||||
 * @param {string} base641 第一个Base64图像数据
 | 
			
		||||
 * @param {number} width1 第一个图像要截取的宽度
 | 
			
		||||
 * @param {string} base642 第二个Base64图像数据
 | 
			
		||||
 * @param {number} width2 第二个图像要截取的宽度
 | 
			
		||||
 * @param {string} [format='image/png'] 输出图像格式
 | 
			
		||||
 * @param {number} [quality=1.0] 输出图像质量(0-1),仅对支持的格式有效
 | 
			
		||||
 * @returns {Promise<string>} 拼接后的Base64图像数据
 | 
			
		||||
 */
 | 
			
		||||
export function combineBase64Images(
 | 
			
		||||
  base641,
 | 
			
		||||
  width1,
 | 
			
		||||
  base642,
 | 
			
		||||
  width2,
 | 
			
		||||
  format = "image/png",
 | 
			
		||||
  quality = 1.0
 | 
			
		||||
) {
 | 
			
		||||
  return new Promise((resolve, reject) => {
 | 
			
		||||
    // 创建canvas元素
 | 
			
		||||
    const canvas = document.createElement("canvas");
 | 
			
		||||
    const ctx = canvas.getContext("2d");
 | 
			
		||||
 | 
			
		||||
    // 设置canvas宽度和高度
 | 
			
		||||
    canvas.width = width1 + width2;
 | 
			
		||||
    canvas.height = 0; // 高度将在图像加载后确定
 | 
			
		||||
 | 
			
		||||
    // 创建图像对象
 | 
			
		||||
    const img1 = new Image();
 | 
			
		||||
    const img2 = new Image();
 | 
			
		||||
 | 
			
		||||
    // 错误处理
 | 
			
		||||
    function handleError(error) {
 | 
			
		||||
      reject(new Error(`图像处理错误: ${error.message}`));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // 监听两个图像都加载完成
 | 
			
		||||
    let loadedCount = 0;
 | 
			
		||||
    function checkAllLoaded() {
 | 
			
		||||
      loadedCount++;
 | 
			
		||||
      if (loadedCount === 2) {
 | 
			
		||||
        drawAndResolve();
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // 图像1加载事件
 | 
			
		||||
    img1.onload = function () {
 | 
			
		||||
      checkAllLoaded();
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    // 图像2加载事件
 | 
			
		||||
    img2.onload = function () {
 | 
			
		||||
      checkAllLoaded();
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    // 图像加载错误事件
 | 
			
		||||
    img1.onerror = img2.onerror = handleError;
 | 
			
		||||
 | 
			
		||||
    // 加载图像
 | 
			
		||||
    img1.src = base641;
 | 
			
		||||
    img2.src = base642;
 | 
			
		||||
 | 
			
		||||
    // 绘制图像并解析为Base64
 | 
			
		||||
    function drawAndResolve() {
 | 
			
		||||
      try {
 | 
			
		||||
        // 确定canvas高度为两个图像高度的最大值
 | 
			
		||||
        const height1 = img1.height;
 | 
			
		||||
        const height2 = img2.height;
 | 
			
		||||
        canvas.height = Math.max(height1, height2);
 | 
			
		||||
 | 
			
		||||
        // 清除画布
 | 
			
		||||
        ctx.clearRect(0, 0, canvas.width, canvas.height);
 | 
			
		||||
 | 
			
		||||
        // 绘制第一个图像的左侧部分 (从左往右截取width1)
 | 
			
		||||
        ctx.drawImage(img1, 0, 0, width1, height1, 0, 0, width1, canvas.height);
 | 
			
		||||
 | 
			
		||||
        // 绘制第二个图像的右侧部分 (从右往左截取width2)
 | 
			
		||||
        // 计算在原图上的截取起点 (从右侧开始)
 | 
			
		||||
        const sourceX = img2.width - width2;
 | 
			
		||||
        ctx.drawImage(
 | 
			
		||||
          img2,
 | 
			
		||||
          sourceX,
 | 
			
		||||
          0,
 | 
			
		||||
          width2,
 | 
			
		||||
          height2,
 | 
			
		||||
          width1,
 | 
			
		||||
          0,
 | 
			
		||||
          width2,
 | 
			
		||||
          canvas.height
 | 
			
		||||
        );
 | 
			
		||||
 | 
			
		||||
        // 将canvas内容转换为Base64
 | 
			
		||||
        const resultBase64 = canvas.toDataURL(format, quality);
 | 
			
		||||
        resolve(resultBase64);
 | 
			
		||||
      } catch (error) {
 | 
			
		||||
        handleError(error);
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  });
 | 
			
		||||
}
 | 
			
		||||
@ -1,3 +1,4 @@
 | 
			
		||||
const { ipcRenderer } = require('electron')
 | 
			
		||||
export const $changeComponentShow = (selector: any, state: any, styleStr: any = false) => {
 | 
			
		||||
  $(selector).css({ visibility: state ? 'visible' : 'hidden' })
 | 
			
		||||
  if (styleStr) {
 | 
			
		||||
@ -17,3 +18,13 @@ export const $changeComponentPop = (selector: any, state: any, styleStr: any = f
 | 
			
		||||
    if (str[0] === 'z-index') $(selector).css({ zIndex: str[1] })
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export const $sendElectronChanel = (chanel: any, arg: any = null) => {
 | 
			
		||||
  console.log('发送给electron', chanel, arg);
 | 
			
		||||
  ipcRenderer.send(chanel, arg);
 | 
			
		||||
};
 | 
			
		||||
export const $recvElectronChanel = (chanel: any, cb: any) => {
 | 
			
		||||
  console.log('接收来自electron', chanel);
 | 
			
		||||
  ipcRenderer.once(chanel, cb);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -128,28 +128,28 @@ const menuList: any = ref([
 | 
			
		||||
    // fun: this.showSecondMenu,
 | 
			
		||||
    key: 'tool',
 | 
			
		||||
    children: [
 | 
			
		||||
      // 'routePlan',
 | 
			
		||||
      // 'clearRoute',
 | 
			
		||||
      // 'graffiti',
 | 
			
		||||
      // // stopGraffiti: "结束涂鸦",
 | 
			
		||||
      // 'clearGraffiti',
 | 
			
		||||
      // 'path',
 | 
			
		||||
      // 'coorLocation',
 | 
			
		||||
      // 'mouseLocation',
 | 
			
		||||
      // 'annotationAggregation',
 | 
			
		||||
      // 'annotation',
 | 
			
		||||
      // 'screenShot',
 | 
			
		||||
      // 'highQuality',
 | 
			
		||||
      // 'videoRecord',
 | 
			
		||||
      // 'pressModel',
 | 
			
		||||
      // 'terrainDig',
 | 
			
		||||
      // 'tilesetClipping',
 | 
			
		||||
      // 'clearTilesetClipping',
 | 
			
		||||
      // 'projConvert',
 | 
			
		||||
      // 'projectionConvert',
 | 
			
		||||
      // 'gdbImport',
 | 
			
		||||
      // 'circleStatistics',
 | 
			
		||||
      // 'polygonStatistics'
 | 
			
		||||
      'routePlan',
 | 
			
		||||
      'clearRoute',
 | 
			
		||||
      'graffiti',
 | 
			
		||||
      // stopGraffiti: "结束涂鸦",
 | 
			
		||||
      'clearGraffiti',
 | 
			
		||||
      'path',
 | 
			
		||||
      'coorLocation',
 | 
			
		||||
      'mouseLocation',
 | 
			
		||||
      'annotationAggregation',
 | 
			
		||||
      'annotation',
 | 
			
		||||
      'screenShot',
 | 
			
		||||
      'highQuality',
 | 
			
		||||
      'videoRecord',
 | 
			
		||||
      'pressModel',
 | 
			
		||||
      'terrainDig',
 | 
			
		||||
      'tilesetClipping',
 | 
			
		||||
      'clearTilesetClipping',
 | 
			
		||||
      'projConvert',
 | 
			
		||||
      'projectionConvert',
 | 
			
		||||
      'gdbImport',
 | 
			
		||||
      'circleStatistics',
 | 
			
		||||
      'polygonStatistics'
 | 
			
		||||
    ]
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
 | 
			
		||||
@ -22,6 +22,11 @@ import { ref, reactive, getCurrentInstance } from 'vue'
 | 
			
		||||
import { useTreeNode } from '../tree/hooks/treeNode'
 | 
			
		||||
import { TreeApi } from '@/api/tree'
 | 
			
		||||
import { renderMethods } from '../tree/hooks/renderTreeNode'
 | 
			
		||||
import { processBase64Images, combineBase64Images } from '@/utils/HighDefinitionScreenshot'
 | 
			
		||||
import { $sendElectronChanel, $recvElectronChanel } from '@/utils/communication'
 | 
			
		||||
import { ElMessage } from 'element-plus'
 | 
			
		||||
import dayjs from 'dayjs'
 | 
			
		||||
import fs from 'fs'
 | 
			
		||||
const { proxy } = getCurrentInstance()
 | 
			
		||||
const { t } = useI18n()
 | 
			
		||||
const { findParentId, findTreeIndex, cusAddNodes } = useTreeNode()
 | 
			
		||||
@ -43,7 +48,7 @@ eventBus.on('graffitiObj', (data) => {
 | 
			
		||||
})
 | 
			
		||||
const methodMap = {
 | 
			
		||||
  // 轨迹运动
 | 
			
		||||
  trajectoryMotion: ()=>{
 | 
			
		||||
  trajectoryMotion: () => {
 | 
			
		||||
    // let draw = new YJ.Draw.DrawPolyline(window.earth)
 | 
			
		||||
    // draw.start((err, positions) => {
 | 
			
		||||
    //   if (positions.length > 1) {}
 | 
			
		||||
@ -83,7 +88,7 @@ const methodMap = {
 | 
			
		||||
        // console.log('addOtherSource', res)
 | 
			
		||||
        // 上树
 | 
			
		||||
        cusAddNodes(window.treeObj, params.parentId, [params])
 | 
			
		||||
        eventBus.emit("openDialog", 'wallStereoscopic');
 | 
			
		||||
        eventBus.emit('openDialog', 'wallStereoscopic')
 | 
			
		||||
      }
 | 
			
		||||
    })
 | 
			
		||||
  },
 | 
			
		||||
@ -223,14 +228,70 @@ const methodMap = {
 | 
			
		||||
  //卷帘对比
 | 
			
		||||
  annotation() {
 | 
			
		||||
    clickChange.annotation = !clickChange.annotation
 | 
			
		||||
    // if (clickChange.annotation) {
 | 
			
		||||
    //   YJ.Global.splitScreen.on(window.earth)
 | 
			
		||||
    // } else {
 | 
			
		||||
    //   YJ.Global.splitScreen.off()
 | 
			
		||||
    // }
 | 
			
		||||
    if (clickChange.annotation) {
 | 
			
		||||
      YJ.Global.splitScreen.on(window.earth)
 | 
			
		||||
    } else {
 | 
			
		||||
      YJ.Global.splitScreen.off()
 | 
			
		||||
    }
 | 
			
		||||
  },
 | 
			
		||||
  //屏幕截图
 | 
			
		||||
  screenShot() {},
 | 
			
		||||
  async screenShot() {
 | 
			
		||||
    function downloadScreen(res) {
 | 
			
		||||
      let base64 = res.replace(/^data:image\/\w+;base64,/, '')
 | 
			
		||||
      console.log('base64', base64)
 | 
			
		||||
      let dataBuffer = new Buffer(base64, 'base64')
 | 
			
		||||
      $sendElectronChanel('saveFile', {
 | 
			
		||||
        title: '保存图片',
 | 
			
		||||
        filename: dayjs().format('YYYYMMDDHHmmss') + '截图',
 | 
			
		||||
        filters: [{ name: '保存图片', extensions: ['jpg'] }]
 | 
			
		||||
      })
 | 
			
		||||
      $recvElectronChanel('selectedFileItem', (e, path) => {
 | 
			
		||||
        console.log('path', fs.writeFile)
 | 
			
		||||
        fs.writeFile(path, dataBuffer, (res) => {
 | 
			
		||||
          console.log(res)
 | 
			
		||||
        })
 | 
			
		||||
      })
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (window.splitScreen || window.multiViewportMode) {
 | 
			
		||||
      let res = ''
 | 
			
		||||
      let res2 = ''
 | 
			
		||||
      let sdk
 | 
			
		||||
      if (window.splitScreen) {
 | 
			
		||||
        sdk = YJ.Global.splitScreen.getSdk()
 | 
			
		||||
      } else {
 | 
			
		||||
        sdk = YJ.Global.multiViewportMode.getSdk()
 | 
			
		||||
      }
 | 
			
		||||
      await new YJ.Global.ScreenShot(sdk.sdkD, (data) => {
 | 
			
		||||
        res = data
 | 
			
		||||
      })
 | 
			
		||||
      await new YJ.Global.ScreenShot(sdk.sdkP, (data) => {
 | 
			
		||||
        res2 = data
 | 
			
		||||
      })
 | 
			
		||||
      if (window.multiViewportMode) {
 | 
			
		||||
        processBase64Images(res, res2, (mergedBase64) => {
 | 
			
		||||
          downloadScreen(mergedBase64)
 | 
			
		||||
          // window.multiViewportMode = false;
 | 
			
		||||
        })
 | 
			
		||||
      } else {
 | 
			
		||||
        let doms = document.querySelectorAll('.cesium-widget')
 | 
			
		||||
        let leftWidth = doms[0].offsetWidth
 | 
			
		||||
        let rightWidth = doms[1].offsetWidth
 | 
			
		||||
        combineBase64Images(res2, leftWidth, res, rightWidth)
 | 
			
		||||
          .then((result) => {
 | 
			
		||||
            downloadScreen(result)
 | 
			
		||||
            // window.splitScreen  = false;
 | 
			
		||||
          })
 | 
			
		||||
          .catch((err) => console.error('拼接失败:', err))
 | 
			
		||||
      }
 | 
			
		||||
    } else {
 | 
			
		||||
      let res = ''
 | 
			
		||||
      await new YJ.Global.ScreenShot(window.earth, (data) => {
 | 
			
		||||
        res = data
 | 
			
		||||
      })
 | 
			
		||||
      downloadScreen(res)
 | 
			
		||||
    }
 | 
			
		||||
  },
 | 
			
		||||
  //高清出图
 | 
			
		||||
  highQuality() {
 | 
			
		||||
    // eventBus.emit('screenShotDialog')
 | 
			
		||||
@ -239,27 +300,130 @@ const methodMap = {
 | 
			
		||||
  //视频录制
 | 
			
		||||
  videoRecord() {
 | 
			
		||||
    clickChange.videoRecord = !clickChange.videoRecord
 | 
			
		||||
 | 
			
		||||
    let time = 3
 | 
			
		||||
    this.$changeComponentShow('#secondMenu', false)
 | 
			
		||||
    // const onKeyDown = (e) => {
 | 
			
		||||
 | 
			
		||||
    //   if (e.keyCode === 27) {
 | 
			
		||||
    //     item.status = !item.status;
 | 
			
		||||
    //     $sendElectronChanel("endRecoder");
 | 
			
		||||
    //     document.removeEventListener("keydown", onKeyDown);
 | 
			
		||||
    //   }
 | 
			
		||||
    // };
 | 
			
		||||
    if (clickChange.videoRecord) {
 | 
			
		||||
      // document.addEventListener("keydown", onKeyDown);
 | 
			
		||||
      let loading = $root_home.openLoading(time, {
 | 
			
		||||
        background: 'rgba(0,0,0,0)',
 | 
			
		||||
        fullscreen: false,
 | 
			
		||||
        customClass: 'timer'
 | 
			
		||||
      })
 | 
			
		||||
      let timer = ''
 | 
			
		||||
      const p = document.createElement('p')
 | 
			
		||||
      p.style.color = '#fff'
 | 
			
		||||
      p.innerHTML = '再次点击录制结束'
 | 
			
		||||
      document.getElementsByClassName('el-loading-spinner')[0].appendChild(p)
 | 
			
		||||
      let func = () => {
 | 
			
		||||
        loading.setText(time--)
 | 
			
		||||
        if (time == -1) {
 | 
			
		||||
          clearInterval(timer)
 | 
			
		||||
          loading.close()
 | 
			
		||||
          console.log('开始了')
 | 
			
		||||
          p.remove()
 | 
			
		||||
          $sendElectronChanel('startRecoder')
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
      func()
 | 
			
		||||
      timer = setInterval(func, 1000)
 | 
			
		||||
    } else {
 | 
			
		||||
      $sendElectronChanel('endRecoder')
 | 
			
		||||
      // document.removeEventListener("keydown", onKeyDown);
 | 
			
		||||
    }
 | 
			
		||||
  },
 | 
			
		||||
  //压模
 | 
			
		||||
  pressModel() {},
 | 
			
		||||
  //地形开挖
 | 
			
		||||
  terrainDig() {
 | 
			
		||||
    // if (window.checkAuthIsValid) {
 | 
			
		||||
    // new YJ.Analysis.TerrainExcavation(window.Earth1);
 | 
			
		||||
    eventBus.emit('terrainExcavationDialog')
 | 
			
		||||
    // } else {
 | 
			
		||||
    //   this.$message({
 | 
			
		||||
    //     message: '您没有该功能的权限',
 | 
			
		||||
    //     type: 'warning'
 | 
			
		||||
    //   })
 | 
			
		||||
    // }
 | 
			
		||||
  },
 | 
			
		||||
  //剖切
 | 
			
		||||
  tilesetClipping() {},
 | 
			
		||||
  tilesetClipping() {
 | 
			
		||||
    // if (window.checkAuthIsValid) {
 | 
			
		||||
    let selectedNode = window.treeObj.getSelectedNodes()
 | 
			
		||||
    if (selectedNode.length < 1) {
 | 
			
		||||
      ElMessage({
 | 
			
		||||
        message: '请在图层指挥舱选中对应模型进行操作',
 | 
			
		||||
        type: 'warning'
 | 
			
		||||
      })
 | 
			
		||||
      return
 | 
			
		||||
    }
 | 
			
		||||
    if (!(selectedNode[0].sourceType === 'tileset' || selectedNode[0].sourceType === 'bim')) {
 | 
			
		||||
      ElMessage({
 | 
			
		||||
        message: '选中的节点不能进行剖切',
 | 
			
		||||
        type: 'warning'
 | 
			
		||||
      })
 | 
			
		||||
      return
 | 
			
		||||
    }
 | 
			
		||||
    let tileset = window.earth.entityMap.get(selectedNode[0].id)
 | 
			
		||||
    let draw = new YJ.Draw.DrawPolygon(window.earth)
 | 
			
		||||
    draw.start((err, pos) => {
 | 
			
		||||
      let section = new YJ.Analysis.Section(window.earth, tileset.entity, {
 | 
			
		||||
        positions: pos
 | 
			
		||||
      })
 | 
			
		||||
      // _entityMap.set(selectedNode.source_id + 'pouqie', section)
 | 
			
		||||
    })
 | 
			
		||||
    // } else {
 | 
			
		||||
    //   this.$message({
 | 
			
		||||
    //     message: '您没有该功能的权限',
 | 
			
		||||
    //     type: 'warning'
 | 
			
		||||
    //   })
 | 
			
		||||
    // }
 | 
			
		||||
  },
 | 
			
		||||
  //删除剖切
 | 
			
		||||
  clearTilesetClipping() {},
 | 
			
		||||
  clearTilesetClipping() {
 | 
			
		||||
    YJ.Analysis.ClearSection()
 | 
			
		||||
  },
 | 
			
		||||
  //度分秒
 | 
			
		||||
  projConvert() {},
 | 
			
		||||
  projConvert() {
 | 
			
		||||
    eventBus.emit('projConvertDialog')
 | 
			
		||||
  },
 | 
			
		||||
  //投影转换
 | 
			
		||||
  projectionConvert() {},
 | 
			
		||||
  projectionConvert() {
 | 
			
		||||
    eventBus.emit('ProjectionConvertDialog')
 | 
			
		||||
  },
 | 
			
		||||
  //GDB导入
 | 
			
		||||
  gdbImport() {},
 | 
			
		||||
  //圆形统计
 | 
			
		||||
  circleStatistics() {},
 | 
			
		||||
  circleStatistics() {
 | 
			
		||||
    // if (window.checkAuthIsValid) {
 | 
			
		||||
    eventBus.emit('goodsSearchCircleDialog')
 | 
			
		||||
    // } else {
 | 
			
		||||
    //   this.$message({
 | 
			
		||||
    //     message: '您没有该功能的权限',
 | 
			
		||||
    //     type: 'warning'
 | 
			
		||||
    //   })
 | 
			
		||||
    // }
 | 
			
		||||
  },
 | 
			
		||||
  //多边形统计
 | 
			
		||||
  polygonStatistics() {}
 | 
			
		||||
  polygonStatistics() {
 | 
			
		||||
    // if (window.checkAuthIsValid) {
 | 
			
		||||
    eventBus.emit('goodsSearchPolgonDialog')
 | 
			
		||||
 | 
			
		||||
    // } else {
 | 
			
		||||
    //   this.$message({
 | 
			
		||||
    //     message: "您没有该功能的权限",
 | 
			
		||||
    //     type: "warning",
 | 
			
		||||
    //   });
 | 
			
		||||
    // }
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const handleClick = (value = 'projectionDistanceMeasure') => {
 | 
			
		||||
 | 
			
		||||
@ -13,7 +13,7 @@
 | 
			
		||||
        <div class="row" style="align-items: flex-start">
 | 
			
		||||
          <div class="col" style="flex: 0 0 120px">
 | 
			
		||||
            <span class="label">等高线</span>
 | 
			
		||||
            <input class="btn-switch show" type="checkbox" />
 | 
			
		||||
            <input class="btn-switch show" type="checkbox" v-model="show" />
 | 
			
		||||
          </div>
 | 
			
		||||
        </div>
 | 
			
		||||
      </div>
 | 
			
		||||
@ -145,6 +145,7 @@
 | 
			
		||||
      </div>
 | 
			
		||||
    </template>
 | 
			
		||||
    <template #footer>
 | 
			
		||||
      <button @click="sure">确定</button>
 | 
			
		||||
      <button @click="close">取消</button>
 | 
			
		||||
    </template>
 | 
			
		||||
  </Dialog>
 | 
			
		||||
@ -158,16 +159,24 @@ import Dialog from '@/components/dialog/baseDialog.vue'
 | 
			
		||||
const baseDialog: any = ref(null)
 | 
			
		||||
const eventBus: any = inject('bus')
 | 
			
		||||
 | 
			
		||||
var show: any = ref(true)
 | 
			
		||||
eventBus.on('contourDialog', () => {
 | 
			
		||||
  baseDialog.value?.open()
 | 
			
		||||
  setTimeout(() => {
 | 
			
		||||
    YJ.Global.Contour(window.earth)
 | 
			
		||||
  })
 | 
			
		||||
})
 | 
			
		||||
const closeCallBack = (e) => {}
 | 
			
		||||
const closeCallBack = (e) => {
 | 
			
		||||
  YJ.Global.ContourReset()
 | 
			
		||||
  show.value = true
 | 
			
		||||
}
 | 
			
		||||
const close = (e) => {
 | 
			
		||||
  baseDialog.value?.close()
 | 
			
		||||
}
 | 
			
		||||
const sure = (e) => {
 | 
			
		||||
  YJ.Global.ContourStartDraw(window.earth, show.value)
 | 
			
		||||
  baseDialog.value?.close()
 | 
			
		||||
}
 | 
			
		||||
</script>
 | 
			
		||||
 | 
			
		||||
<style scoped lang="scss"></style>
 | 
			
		||||
 | 
			
		||||
@ -5,6 +5,7 @@
 | 
			
		||||
    title="坐标定位"
 | 
			
		||||
    left="180px"
 | 
			
		||||
    top="100px"
 | 
			
		||||
    width="418px"
 | 
			
		||||
    :closeCallback="closeCallBack"
 | 
			
		||||
  >
 | 
			
		||||
    <template #content>
 | 
			
		||||
@ -177,13 +178,13 @@ const flyto = (e) => {
 | 
			
		||||
      break
 | 
			
		||||
    case 'third':
 | 
			
		||||
      var lng =
 | 
			
		||||
      // @ts-ignore (define in dts)
 | 
			
		||||
        // @ts-ignore (define in dts)
 | 
			
		||||
        Math.abs(longitude.value) + Math.abs(lngMin.value) / 60 + Math.abs(lngSec.value) / 3600
 | 
			
		||||
      var lat =
 | 
			
		||||
      // @ts-ignore (define in dts)
 | 
			
		||||
        // @ts-ignore (define in dts)
 | 
			
		||||
        Math.abs(latitude.value) + Math.abs(latMin.value) / 60 + Math.abs(latSec.value) / 3600
 | 
			
		||||
 | 
			
		||||
        // @ts-ignore (define in dts)
 | 
			
		||||
      // @ts-ignore (define in dts)
 | 
			
		||||
      lng = longitude.value < 0 ? -lng : lng
 | 
			
		||||
      // @ts-ignore (define in dts)
 | 
			
		||||
      lat = latitude.value < 0 ? -lat : lat
 | 
			
		||||
 | 
			
		||||
@ -0,0 +1,340 @@
 | 
			
		||||
<template>
 | 
			
		||||
  <Dialog
 | 
			
		||||
    v-if="show"
 | 
			
		||||
    ref="baseDialog"
 | 
			
		||||
    title="物质统计"
 | 
			
		||||
    left="180px"
 | 
			
		||||
    top="100px"
 | 
			
		||||
    :closeCallback="closeCallBack"
 | 
			
		||||
  >
 | 
			
		||||
    <template #content>
 | 
			
		||||
      <div id="goodSearchEchart" style="width: 100%; height: 100%"></div>
 | 
			
		||||
    </template>
 | 
			
		||||
    <template #footer>
 | 
			
		||||
      <button>绘制</button>
 | 
			
		||||
    </template>
 | 
			
		||||
  </Dialog>
 | 
			
		||||
</template>
 | 
			
		||||
 | 
			
		||||
<script setup lang="ts">
 | 
			
		||||
import { ref, reactive } from 'vue'
 | 
			
		||||
import { inject } from 'vue'
 | 
			
		||||
import { nextTick } from 'vue'
 | 
			
		||||
import { ElMessage } from 'element-plus'
 | 
			
		||||
import Dialog from '@/components/dialog/baseDialog.vue'
 | 
			
		||||
 | 
			
		||||
const baseDialog: any = ref(null)
 | 
			
		||||
const eventBus: any = inject('bus')
 | 
			
		||||
const shpTotalDict: any = reactive({
 | 
			
		||||
  shlwz_jzzp: '救灾帐篷',
 | 
			
		||||
  mb: '棉被',
 | 
			
		||||
  mymdy: '棉衣、棉大衣',
 | 
			
		||||
  mjb: '毛巾被',
 | 
			
		||||
  mt: '毛毯',
 | 
			
		||||
  dgnsd: '睡袋',
 | 
			
		||||
  zdc: '折叠床',
 | 
			
		||||
  jycs: '简易厕所',
 | 
			
		||||
  xpct: '橡皮船(艇)',
 | 
			
		||||
  cfz: '冲锋舟',
 | 
			
		||||
  jsc: '救生船',
 | 
			
		||||
  jsy: '救生衣',
 | 
			
		||||
  jsq: '救生圈',
 | 
			
		||||
  bzd: '编织袋',
 | 
			
		||||
  md: '麻袋',
 | 
			
		||||
  csb: '抽水泵',
 | 
			
		||||
  fdj: '发电机',
 | 
			
		||||
  yjd: '应急灯',
 | 
			
		||||
  jzzp: '救灾帐篷',
 | 
			
		||||
  jzyb: '救灾衣被',
 | 
			
		||||
  jygj: '救援工具'
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
var draw: any = reactive([])
 | 
			
		||||
 | 
			
		||||
var show: any = ref(false)
 | 
			
		||||
eventBus.on('goodsSearchCircleDialog', () => {
 | 
			
		||||
  console.log('kkkkkk')
 | 
			
		||||
  // baseDialog.value?.open()
 | 
			
		||||
  draw = new YJ.Draw.DrawCircle(window.earth)
 | 
			
		||||
  draw.start((err, positions) => {
 | 
			
		||||
    console.log('err, positions', err, positions)
 | 
			
		||||
    if (!err && positions.center.lng) {
 | 
			
		||||
      show.value = true
 | 
			
		||||
      let nodes = booleanOverlaps(positions)
 | 
			
		||||
      console.log('goodsSearchCircle', nodes)
 | 
			
		||||
      renderCanvas(nodes)
 | 
			
		||||
    }
 | 
			
		||||
  })
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
function booleanOverlaps(positions1, flag = 'circle') {
 | 
			
		||||
  let cross = undefined
 | 
			
		||||
  function set3Array(positions) {
 | 
			
		||||
    let arr = []
 | 
			
		||||
    positions.forEach((item) => {
 | 
			
		||||
      arr.push([item.lng, item.lat])
 | 
			
		||||
    })
 | 
			
		||||
    arr.push(arr[0])
 | 
			
		||||
    return arr
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  let getNode = (types) => {
 | 
			
		||||
    let treeObj = window.treeObj
 | 
			
		||||
    let res = []
 | 
			
		||||
    types.forEach((type) => {
 | 
			
		||||
      let nodes = treeObj.getNodesByParam('sourceType', type, null)
 | 
			
		||||
      // console.log("nodes",nodes)
 | 
			
		||||
      res = res.concat(nodes)
 | 
			
		||||
    })
 | 
			
		||||
    return res
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  //绘制的区域
 | 
			
		||||
  // console.log("[set3Array(positions1)]", [set3Array(positions1)])
 | 
			
		||||
  // 获取物资处(特定的标注类型)
 | 
			
		||||
  let allNodes = getNode(['point', 'vr', 'picture', 'Feature'])
 | 
			
		||||
  console.log('allNodes', allNodes)
 | 
			
		||||
  let itemInArea = [] //区域内的类型符合的标注
 | 
			
		||||
 | 
			
		||||
  for (let i = 0; i < allNodes.length; i++) {
 | 
			
		||||
    let item = allNodes[i]
 | 
			
		||||
    let getAllItemInArea = (lng, lat) => {
 | 
			
		||||
      if (flag == 'circle') {
 | 
			
		||||
        let { center, radius } = positions1
 | 
			
		||||
        let distance = new YJ.Tools().randomString(center, { lng, lat })
 | 
			
		||||
        distance < radius && itemInArea.push(item)
 | 
			
		||||
      } else {
 | 
			
		||||
        let polygon1 = turf.polygon([set3Array(positions1)])
 | 
			
		||||
        let pt = turf.point([lng, lat])
 | 
			
		||||
        turf.booleanPointInPolygon(pt, polygon1) && itemInArea.push(item)
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
    console.log(item, item.sourceType, 'ooooo')
 | 
			
		||||
    switch (item.sourceType) {
 | 
			
		||||
      case 'point':
 | 
			
		||||
      case 'vr':
 | 
			
		||||
      case 'picture':
 | 
			
		||||
        let params = JSON.parse(item.params)
 | 
			
		||||
        console.log('params', params)
 | 
			
		||||
        let lng = params.position.lng
 | 
			
		||||
        let lat = params.position.lat
 | 
			
		||||
        getAllItemInArea(lng, lat)
 | 
			
		||||
        break
 | 
			
		||||
      case 'Feature':
 | 
			
		||||
        if (item.detail.geometry.type == 'Point') {
 | 
			
		||||
          lng = item.detail.geometry.coordinates[0]
 | 
			
		||||
          lat = item.detail.geometry.coordinates[1]
 | 
			
		||||
          getAllItemInArea(lng, lat)
 | 
			
		||||
        }
 | 
			
		||||
        break
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
  return itemInArea
 | 
			
		||||
}
 | 
			
		||||
function renderCanvas(nodes) {
 | 
			
		||||
  console.log('nodes', nodes)
 | 
			
		||||
 | 
			
		||||
  let x: any = []
 | 
			
		||||
  let y: any = []
 | 
			
		||||
  nodes.forEach((item) => {
 | 
			
		||||
    // shp物资统计
 | 
			
		||||
    if (item.sourceType == 'Feature') {
 | 
			
		||||
      let obj = JSON.parse(JSON.stringify(item.detail.properties))
 | 
			
		||||
      for (const key in obj) {
 | 
			
		||||
        let name = key
 | 
			
		||||
        if (shpTotalDict[key]) {
 | 
			
		||||
          name = shpTotalDict[key]
 | 
			
		||||
          // 把相同名称的物资数量相加,名称相同时,累加数据
 | 
			
		||||
          let index = x.findIndex((item) => item === name)
 | 
			
		||||
          if (index !== -1) {
 | 
			
		||||
            y[index] = y[index] + Number(obj[key])
 | 
			
		||||
          } else {
 | 
			
		||||
            x.push(name)
 | 
			
		||||
            y.push(Number(obj[key]))
 | 
			
		||||
          }
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
    let params = JSON.parse(item.params)
 | 
			
		||||
    if (params.attribute && params.attribute.goods) {
 | 
			
		||||
      let goods = params.attribute.goods.content
 | 
			
		||||
      console.log('goods', goods)
 | 
			
		||||
      if (goods.length) {
 | 
			
		||||
        // $root_home_index.goodSearchDialog = false;
 | 
			
		||||
        goods.forEach((good) => {
 | 
			
		||||
          // 把相同名称的物资数量相加,名称相同时,累加数据
 | 
			
		||||
          let index = x.findIndex((item) => item === good.name)
 | 
			
		||||
          if (index !== -1) {
 | 
			
		||||
            y[index] = y[index] + Number(good.cnt)
 | 
			
		||||
          } else {
 | 
			
		||||
            x.push(good.name)
 | 
			
		||||
            y.push(Number(good.cnt))
 | 
			
		||||
          }
 | 
			
		||||
        })
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  })
 | 
			
		||||
 | 
			
		||||
  console.log('x,y')
 | 
			
		||||
  console.log(x)
 | 
			
		||||
  console.log(y)
 | 
			
		||||
  let notZeroX = []
 | 
			
		||||
  let notZeroY = []
 | 
			
		||||
  for (let i = 0; i < y.length; i++) {
 | 
			
		||||
    if (y[i] != 0) {
 | 
			
		||||
      notZeroX.push(x[i])
 | 
			
		||||
      notZeroY.push(y[i])
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
  console.log(notZeroX)
 | 
			
		||||
  console.log(notZeroY)
 | 
			
		||||
  x = notZeroX
 | 
			
		||||
  y = notZeroY
 | 
			
		||||
  if (!x.length) show.value = false
 | 
			
		||||
  if (show.value) {
 | 
			
		||||
    nextTick(() => {
 | 
			
		||||
      let option = {
 | 
			
		||||
        grid: {
 | 
			
		||||
          top: '20%',
 | 
			
		||||
          left: '5%',
 | 
			
		||||
          right: '5%',
 | 
			
		||||
          bottom: '8%',
 | 
			
		||||
          containLabel: true
 | 
			
		||||
        },
 | 
			
		||||
        tooltip: {
 | 
			
		||||
          trigger: 'axis',
 | 
			
		||||
          axisPointer: {
 | 
			
		||||
            type: 'shadow',
 | 
			
		||||
            label: {
 | 
			
		||||
              show: true
 | 
			
		||||
            }
 | 
			
		||||
          },
 | 
			
		||||
          formatter(params) {
 | 
			
		||||
            var data = ''
 | 
			
		||||
            for (var i = 0; i < params.length; i++) {
 | 
			
		||||
              if (params[i].seriesName == '随访率') {
 | 
			
		||||
                data += params[i].seriesName + ':  ' + params[i].value + '%'
 | 
			
		||||
              } else {
 | 
			
		||||
                data += params[i].seriesName + ':  ' + params[i].value + '<br/>'
 | 
			
		||||
              }
 | 
			
		||||
            }
 | 
			
		||||
            return data
 | 
			
		||||
          }
 | 
			
		||||
        },
 | 
			
		||||
        legend: {
 | 
			
		||||
          data: ['总量'],
 | 
			
		||||
          top: '5%',
 | 
			
		||||
          left: '5%',
 | 
			
		||||
          right: '5%',
 | 
			
		||||
          bottom: '5%',
 | 
			
		||||
          textStyle: {
 | 
			
		||||
            color: '#fff'
 | 
			
		||||
          }
 | 
			
		||||
        },
 | 
			
		||||
        xAxis: {
 | 
			
		||||
          // type: "category",
 | 
			
		||||
          axisLine: {
 | 
			
		||||
            show: false
 | 
			
		||||
          },
 | 
			
		||||
          axisTick: {
 | 
			
		||||
            show: false
 | 
			
		||||
          },
 | 
			
		||||
          axisLabel: {
 | 
			
		||||
            show: true,
 | 
			
		||||
            width: 40, //将内容的宽度固定
 | 
			
		||||
            overflow: 'truncate', //超出的部分截断
 | 
			
		||||
            truncate: '...', //截断的部分用...代替
 | 
			
		||||
            rotate: 30,
 | 
			
		||||
            interval: 0,
 | 
			
		||||
            textStyle: {
 | 
			
		||||
              color: '#fff' //X轴文字颜色
 | 
			
		||||
            }
 | 
			
		||||
          }
 | 
			
		||||
        },
 | 
			
		||||
        yAxis: [
 | 
			
		||||
          {
 | 
			
		||||
            type: 'value',
 | 
			
		||||
            name: '(数量)',
 | 
			
		||||
            nameTextStyle: {
 | 
			
		||||
              color: '#fff'
 | 
			
		||||
            },
 | 
			
		||||
            splitLine: {
 | 
			
		||||
              show: true,
 | 
			
		||||
              lineStyle: {
 | 
			
		||||
                color: '#eeeeee'
 | 
			
		||||
              }
 | 
			
		||||
            },
 | 
			
		||||
            axisTick: {
 | 
			
		||||
              show: false
 | 
			
		||||
            },
 | 
			
		||||
            axisLine: {
 | 
			
		||||
              show: false
 | 
			
		||||
            },
 | 
			
		||||
            axisLabel: {
 | 
			
		||||
              show: true,
 | 
			
		||||
              textStyle: {
 | 
			
		||||
                color: '#fff'
 | 
			
		||||
              }
 | 
			
		||||
            }
 | 
			
		||||
          },
 | 
			
		||||
          {
 | 
			
		||||
            type: 'value',
 | 
			
		||||
            gridIndex: 0,
 | 
			
		||||
            min: 50,
 | 
			
		||||
            max: 100,
 | 
			
		||||
            splitNumber: 8,
 | 
			
		||||
            splitLine: {
 | 
			
		||||
              show: false
 | 
			
		||||
            },
 | 
			
		||||
            axisLine: {
 | 
			
		||||
              show: false
 | 
			
		||||
            },
 | 
			
		||||
            axisTick: {
 | 
			
		||||
              show: false
 | 
			
		||||
            },
 | 
			
		||||
            axisLabel: {
 | 
			
		||||
              show: false
 | 
			
		||||
            },
 | 
			
		||||
            splitArea: {
 | 
			
		||||
              show: false,
 | 
			
		||||
              areaStyle: {
 | 
			
		||||
                color: ['rgba(250,250,250,0.0)', 'rgba(250,250,250,0.05)']
 | 
			
		||||
              }
 | 
			
		||||
            }
 | 
			
		||||
          }
 | 
			
		||||
        ],
 | 
			
		||||
        series: [
 | 
			
		||||
          {
 | 
			
		||||
            name: '数量',
 | 
			
		||||
            type: 'bar',
 | 
			
		||||
            label: {
 | 
			
		||||
              show: true,
 | 
			
		||||
              position: 'top'
 | 
			
		||||
            },
 | 
			
		||||
            barWidth: 15,
 | 
			
		||||
            itemStyle: {
 | 
			
		||||
              normal: {
 | 
			
		||||
                color: '#fdcb6c'
 | 
			
		||||
              }
 | 
			
		||||
            }
 | 
			
		||||
          }
 | 
			
		||||
        ]
 | 
			
		||||
      }
 | 
			
		||||
      var dom = document.getElementById('goodSearchEchart')
 | 
			
		||||
      var myChart = (window as any).echarts.init(dom)
 | 
			
		||||
      option.xAxis.data = x
 | 
			
		||||
      option.series[0].data = y
 | 
			
		||||
      myChart.setOption(option)
 | 
			
		||||
    })
 | 
			
		||||
  } else {
 | 
			
		||||
    ElMessage({
 | 
			
		||||
      message: '该区域没有物资',
 | 
			
		||||
      type: 'warning'
 | 
			
		||||
    })
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const closeCallBack = (e) => {}
 | 
			
		||||
</script>
 | 
			
		||||
 | 
			
		||||
<style scoped lang="scss"></style>
 | 
			
		||||
@ -0,0 +1,328 @@
 | 
			
		||||
<template>
 | 
			
		||||
  <Dialog
 | 
			
		||||
    v-if="show"
 | 
			
		||||
    ref="baseDialog"
 | 
			
		||||
    title="物质统计"
 | 
			
		||||
    left="180px"
 | 
			
		||||
    top="100px"
 | 
			
		||||
    :closeCallback="closeCallBack"
 | 
			
		||||
  >
 | 
			
		||||
    <template #content>
 | 
			
		||||
      <div id="goodSearchEchart2" style="width: 100%; height: 100%"></div>
 | 
			
		||||
    </template>
 | 
			
		||||
    <template #footer>
 | 
			
		||||
      <button>绘制</button>
 | 
			
		||||
    </template>
 | 
			
		||||
  </Dialog>
 | 
			
		||||
</template>
 | 
			
		||||
 | 
			
		||||
<script setup lang="ts">
 | 
			
		||||
import { ref, reactive } from 'vue'
 | 
			
		||||
import { inject } from 'vue'
 | 
			
		||||
import { nextTick } from 'vue'
 | 
			
		||||
import { ElMessage } from 'element-plus'
 | 
			
		||||
import Dialog from '@/components/dialog/baseDialog.vue'
 | 
			
		||||
 | 
			
		||||
const baseDialog: any = ref(null)
 | 
			
		||||
const eventBus: any = inject('bus')
 | 
			
		||||
const shpTotalDict: any = reactive({
 | 
			
		||||
  shlwz_jzzp: '救灾帐篷',
 | 
			
		||||
  mb: '棉被',
 | 
			
		||||
  mymdy: '棉衣、棉大衣',
 | 
			
		||||
  mjb: '毛巾被',
 | 
			
		||||
  mt: '毛毯',
 | 
			
		||||
  dgnsd: '睡袋',
 | 
			
		||||
  zdc: '折叠床',
 | 
			
		||||
  jycs: '简易厕所',
 | 
			
		||||
  xpct: '橡皮船(艇)',
 | 
			
		||||
  cfz: '冲锋舟',
 | 
			
		||||
  jsc: '救生船',
 | 
			
		||||
  jsy: '救生衣',
 | 
			
		||||
  jsq: '救生圈',
 | 
			
		||||
  bzd: '编织袋',
 | 
			
		||||
  md: '麻袋',
 | 
			
		||||
  csb: '抽水泵',
 | 
			
		||||
  fdj: '发电机',
 | 
			
		||||
  yjd: '应急灯',
 | 
			
		||||
  jzzp: '救灾帐篷',
 | 
			
		||||
  jzyb: '救灾衣被',
 | 
			
		||||
  jygj: '救援工具'
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
var draw: any = reactive([])
 | 
			
		||||
 | 
			
		||||
var show: any = ref(false)
 | 
			
		||||
eventBus.on('goodsSearchPolgonDialog', () => {
 | 
			
		||||
  draw = new YJ.Draw.DrawPolygon(window.earth)
 | 
			
		||||
  draw.start((err, params) => {
 | 
			
		||||
    if (!err && params.length > 2) {
 | 
			
		||||
      show.value = true
 | 
			
		||||
      let nodes = booleanOverlaps(params, 'polygon')
 | 
			
		||||
      renderCanvas(nodes)
 | 
			
		||||
    }
 | 
			
		||||
  })
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
function booleanOverlaps(positions1, flag = 'circle') {
 | 
			
		||||
  let cross = undefined
 | 
			
		||||
  function set3Array(positions) {
 | 
			
		||||
    let arr = []
 | 
			
		||||
    positions.forEach((item) => {
 | 
			
		||||
      arr.push([item.lng, item.lat])
 | 
			
		||||
    })
 | 
			
		||||
    arr.push(arr[0])
 | 
			
		||||
    return arr
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  let getNode = (types) => {
 | 
			
		||||
    let treeObj = window.treeObj
 | 
			
		||||
    let res = []
 | 
			
		||||
    types.forEach((type) => {
 | 
			
		||||
      let nodes = treeObj.getNodesByParam('sourceType', type, null)
 | 
			
		||||
      res = res.concat(nodes)
 | 
			
		||||
    })
 | 
			
		||||
    return res
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  //绘制的区域
 | 
			
		||||
  // 获取物资处(特定的标注类型)
 | 
			
		||||
  let allNodes = getNode(['point', 'vr', 'picture', 'Feature'])
 | 
			
		||||
  let itemInArea = [] //区域内的类型符合的标注
 | 
			
		||||
 | 
			
		||||
  for (let i = 0; i < allNodes.length; i++) {
 | 
			
		||||
    let item = allNodes[i]
 | 
			
		||||
    let getAllItemInArea = (lng, lat) => {
 | 
			
		||||
      if (flag == 'circle') {
 | 
			
		||||
        let { center, radius } = positions1
 | 
			
		||||
        let distance = new YJ.Tools().randomString(center, { lng, lat })
 | 
			
		||||
        distance < radius && itemInArea.push(item)
 | 
			
		||||
      } else {
 | 
			
		||||
        let polygon1 = turf.polygon([set3Array(positions1)])
 | 
			
		||||
        let pt = turf.point([lng, lat])
 | 
			
		||||
        turf.booleanPointInPolygon(pt, polygon1) && itemInArea.push(item)
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
    switch (item.sourceType) {
 | 
			
		||||
      case 'point':
 | 
			
		||||
      case 'vr':
 | 
			
		||||
      case 'picture':
 | 
			
		||||
        let params = JSON.parse(item.params)
 | 
			
		||||
        let lng = params.position.lng
 | 
			
		||||
        let lat = params.position.lat
 | 
			
		||||
        getAllItemInArea(lng, lat)
 | 
			
		||||
        break
 | 
			
		||||
      case 'Feature':
 | 
			
		||||
        if (item.detail.geometry.type == 'Point') {
 | 
			
		||||
          lng = item.detail.geometry.coordinates[0]
 | 
			
		||||
          lat = item.detail.geometry.coordinates[1]
 | 
			
		||||
          getAllItemInArea(lng, lat)
 | 
			
		||||
        }
 | 
			
		||||
        break
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
  return itemInArea
 | 
			
		||||
}
 | 
			
		||||
function renderCanvas(nodes) {
 | 
			
		||||
  let x: any = []
 | 
			
		||||
  let y: any = []
 | 
			
		||||
  nodes.forEach((item) => {
 | 
			
		||||
    // shp物资统计
 | 
			
		||||
    if (item.sourceType == 'Feature') {
 | 
			
		||||
      let obj = JSON.parse(JSON.stringify(item.detail.properties))
 | 
			
		||||
      for (const key in obj) {
 | 
			
		||||
        let name = key
 | 
			
		||||
        if (shpTotalDict[key]) {
 | 
			
		||||
          name = shpTotalDict[key]
 | 
			
		||||
          // 把相同名称的物资数量相加,名称相同时,累加数据
 | 
			
		||||
          let index = x.findIndex((item) => item === name)
 | 
			
		||||
          if (index !== -1) {
 | 
			
		||||
            y[index] = y[index] + Number(obj[key])
 | 
			
		||||
          } else {
 | 
			
		||||
            x.push(name)
 | 
			
		||||
            y.push(Number(obj[key]))
 | 
			
		||||
          }
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
    let params = JSON.parse(item.params)
 | 
			
		||||
    if (params.attribute && params.attribute.goods) {
 | 
			
		||||
      let goods = params.attribute.goods.content
 | 
			
		||||
      if (goods.length) {
 | 
			
		||||
        // $root_home_index.goodSearchDialog = false;
 | 
			
		||||
        goods.forEach((good) => {
 | 
			
		||||
          // 把相同名称的物资数量相加,名称相同时,累加数据
 | 
			
		||||
          let index = x.findIndex((item) => item === good.name)
 | 
			
		||||
          if (index !== -1) {
 | 
			
		||||
            y[index] = y[index] + Number(good.cnt)
 | 
			
		||||
          } else {
 | 
			
		||||
            x.push(good.name)
 | 
			
		||||
            y.push(Number(good.cnt))
 | 
			
		||||
          }
 | 
			
		||||
        })
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  })
 | 
			
		||||
 | 
			
		||||
  console.log('x,y')
 | 
			
		||||
  console.log(x)
 | 
			
		||||
  console.log(y)
 | 
			
		||||
  let notZeroX = []
 | 
			
		||||
  let notZeroY = []
 | 
			
		||||
  for (let i = 0; i < y.length; i++) {
 | 
			
		||||
    if (y[i] != 0) {
 | 
			
		||||
      notZeroX.push(x[i])
 | 
			
		||||
      notZeroY.push(y[i])
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
  console.log(notZeroX)
 | 
			
		||||
  console.log(notZeroY)
 | 
			
		||||
  x = notZeroX
 | 
			
		||||
  y = notZeroY
 | 
			
		||||
  if (!x.length) show.value = false
 | 
			
		||||
  if (show.value) {
 | 
			
		||||
    nextTick(() => {
 | 
			
		||||
      let option = {
 | 
			
		||||
        grid: {
 | 
			
		||||
          top: '20%',
 | 
			
		||||
          left: '5%',
 | 
			
		||||
          right: '5%',
 | 
			
		||||
          bottom: '8%',
 | 
			
		||||
          containLabel: true
 | 
			
		||||
        },
 | 
			
		||||
        tooltip: {
 | 
			
		||||
          trigger: 'axis',
 | 
			
		||||
          axisPointer: {
 | 
			
		||||
            type: 'shadow',
 | 
			
		||||
            label: {
 | 
			
		||||
              show: true
 | 
			
		||||
            }
 | 
			
		||||
          },
 | 
			
		||||
          formatter(params) {
 | 
			
		||||
            var data = ''
 | 
			
		||||
            for (var i = 0; i < params.length; i++) {
 | 
			
		||||
              if (params[i].seriesName == '随访率') {
 | 
			
		||||
                data += params[i].seriesName + ':  ' + params[i].value + '%'
 | 
			
		||||
              } else {
 | 
			
		||||
                data += params[i].seriesName + ':  ' + params[i].value + '<br/>'
 | 
			
		||||
              }
 | 
			
		||||
            }
 | 
			
		||||
            return data
 | 
			
		||||
          }
 | 
			
		||||
        },
 | 
			
		||||
        legend: {
 | 
			
		||||
          data: ['总量'],
 | 
			
		||||
          top: '5%',
 | 
			
		||||
          left: '5%',
 | 
			
		||||
          right: '5%',
 | 
			
		||||
          bottom: '5%',
 | 
			
		||||
          textStyle: {
 | 
			
		||||
            color: '#fff'
 | 
			
		||||
          }
 | 
			
		||||
        },
 | 
			
		||||
        xAxis: {
 | 
			
		||||
          // type: "category",
 | 
			
		||||
          axisLine: {
 | 
			
		||||
            show: false
 | 
			
		||||
          },
 | 
			
		||||
          axisTick: {
 | 
			
		||||
            show: false
 | 
			
		||||
          },
 | 
			
		||||
          axisLabel: {
 | 
			
		||||
            show: true,
 | 
			
		||||
            width: 40, //将内容的宽度固定
 | 
			
		||||
            overflow: 'truncate', //超出的部分截断
 | 
			
		||||
            truncate: '...', //截断的部分用...代替
 | 
			
		||||
            rotate: 30,
 | 
			
		||||
            interval: 0,
 | 
			
		||||
            textStyle: {
 | 
			
		||||
              color: '#fff' //X轴文字颜色
 | 
			
		||||
            }
 | 
			
		||||
          }
 | 
			
		||||
        },
 | 
			
		||||
        yAxis: [
 | 
			
		||||
          {
 | 
			
		||||
            type: 'value',
 | 
			
		||||
            name: '(数量)',
 | 
			
		||||
            nameTextStyle: {
 | 
			
		||||
              color: '#fff'
 | 
			
		||||
            },
 | 
			
		||||
            splitLine: {
 | 
			
		||||
              show: true,
 | 
			
		||||
              lineStyle: {
 | 
			
		||||
                color: '#eeeeee'
 | 
			
		||||
              }
 | 
			
		||||
            },
 | 
			
		||||
            axisTick: {
 | 
			
		||||
              show: false
 | 
			
		||||
            },
 | 
			
		||||
            axisLine: {
 | 
			
		||||
              show: false
 | 
			
		||||
            },
 | 
			
		||||
            axisLabel: {
 | 
			
		||||
              show: true,
 | 
			
		||||
              textStyle: {
 | 
			
		||||
                color: '#fff'
 | 
			
		||||
              }
 | 
			
		||||
            }
 | 
			
		||||
          },
 | 
			
		||||
          {
 | 
			
		||||
            type: 'value',
 | 
			
		||||
            gridIndex: 0,
 | 
			
		||||
            min: 50,
 | 
			
		||||
            max: 100,
 | 
			
		||||
            splitNumber: 8,
 | 
			
		||||
            splitLine: {
 | 
			
		||||
              show: false
 | 
			
		||||
            },
 | 
			
		||||
            axisLine: {
 | 
			
		||||
              show: false
 | 
			
		||||
            },
 | 
			
		||||
            axisTick: {
 | 
			
		||||
              show: false
 | 
			
		||||
            },
 | 
			
		||||
            axisLabel: {
 | 
			
		||||
              show: false
 | 
			
		||||
            },
 | 
			
		||||
            splitArea: {
 | 
			
		||||
              show: false,
 | 
			
		||||
              areaStyle: {
 | 
			
		||||
                color: ['rgba(250,250,250,0.0)', 'rgba(250,250,250,0.05)']
 | 
			
		||||
              }
 | 
			
		||||
            }
 | 
			
		||||
          }
 | 
			
		||||
        ],
 | 
			
		||||
        series: [
 | 
			
		||||
          {
 | 
			
		||||
            name: '数量',
 | 
			
		||||
            type: 'bar',
 | 
			
		||||
            label: {
 | 
			
		||||
              show: true,
 | 
			
		||||
              position: 'top'
 | 
			
		||||
            },
 | 
			
		||||
            barWidth: 15,
 | 
			
		||||
            itemStyle: {
 | 
			
		||||
              normal: {
 | 
			
		||||
                color: '#fdcb6c'
 | 
			
		||||
              }
 | 
			
		||||
            }
 | 
			
		||||
          }
 | 
			
		||||
        ]
 | 
			
		||||
      }
 | 
			
		||||
      var dom = document.getElementById('goodSearchEchart2')
 | 
			
		||||
      var myChart = (window as any).echarts.init(dom)
 | 
			
		||||
      option.xAxis.data = x
 | 
			
		||||
      option.series[0].data = y
 | 
			
		||||
      myChart.setOption(option)
 | 
			
		||||
    })
 | 
			
		||||
  } else {
 | 
			
		||||
    ElMessage({
 | 
			
		||||
      message: '该区域没有物资',
 | 
			
		||||
      type: 'warning'
 | 
			
		||||
    })
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const closeCallBack = (e) => {}
 | 
			
		||||
</script>
 | 
			
		||||
 | 
			
		||||
<style scoped lang="scss"></style>
 | 
			
		||||
@ -59,7 +59,7 @@ eventBus.on('graffitiDialog', () => {
 | 
			
		||||
    graffiti = new YJ.Obj.Graffiti(window.earth, {
 | 
			
		||||
      width: width.value
 | 
			
		||||
    })
 | 
			
		||||
  }, 0)
 | 
			
		||||
  }, 10)
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
const closeCallBack = (e) => {}
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										283
									
								
								src/renderer/src/views/components/propertyBox/ProjConvert.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										283
									
								
								src/renderer/src/views/components/propertyBox/ProjConvert.vue
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,283 @@
 | 
			
		||||
<template>
 | 
			
		||||
  <Dialog
 | 
			
		||||
    ref="baseDialog"
 | 
			
		||||
    class="proj-convert"
 | 
			
		||||
    title="度分秒格式转换"
 | 
			
		||||
    left="180px"
 | 
			
		||||
    top="100px"
 | 
			
		||||
    width="515px"
 | 
			
		||||
    :closeCallback="closeCallBack"
 | 
			
		||||
  >
 | 
			
		||||
    <template #content v-if="status1">
 | 
			
		||||
      <span class="custom-divider"></span>
 | 
			
		||||
      <div class="div-item">
 | 
			
		||||
        <div class="row">
 | 
			
		||||
          <div class="col input-select-box">
 | 
			
		||||
            <span class="label" style="flex: 0 0 60px">输入格式</span>
 | 
			
		||||
            <div class="input-select"></div>
 | 
			
		||||
          </div>
 | 
			
		||||
        </div>
 | 
			
		||||
      </div>
 | 
			
		||||
      <div class="div-item item" data-type="0">
 | 
			
		||||
        <span class="custom-divider"></span>
 | 
			
		||||
        <p style="font-size: 16px; padding-bottom: 6px; margin-top: 10px; margin-bottom: 5px">
 | 
			
		||||
          <span style="margin-right: 10px">度</span>
 | 
			
		||||
          <span style="font-size: 12px; margin-bottom: 5px; color: #f16c55">例如116.6°, 39.9°</span>
 | 
			
		||||
        </p>
 | 
			
		||||
        <div class="row">
 | 
			
		||||
          <div class="col">
 | 
			
		||||
            <span class="label" style="flex: auto">经度</span>
 | 
			
		||||
            <input class="input lng" type="number" min="-180" max="180" value="0" title="" />
 | 
			
		||||
          </div>
 | 
			
		||||
          <div class="col" style="margin: 0">
 | 
			
		||||
            <span class="label">纬度</span>
 | 
			
		||||
            <input class="input lat" type="number" min="-90" max="90" value="0" title="" />
 | 
			
		||||
          </div>
 | 
			
		||||
          <div class="col" style="flex: 0 0 24px">
 | 
			
		||||
            <i
 | 
			
		||||
              class="icon-copy-box"
 | 
			
		||||
              title="复制"
 | 
			
		||||
              data-clipboard-action="copy"
 | 
			
		||||
              data-clipboard-target=".input"
 | 
			
		||||
              style="cursor: pointer"
 | 
			
		||||
            >
 | 
			
		||||
              <svg class="icon-copy" style="margin: 4px; margin-bottom: 0px">
 | 
			
		||||
                <use xlink:href="#yj-icon-copy"></use>
 | 
			
		||||
              </svg>
 | 
			
		||||
            </i>
 | 
			
		||||
            <button class="convert" style="margin-left: 10px">转 换</button>
 | 
			
		||||
          </div>
 | 
			
		||||
        </div>
 | 
			
		||||
      </div>
 | 
			
		||||
      <div class="div-item item" data-type="1">
 | 
			
		||||
        <span class="custom-divider"></span>
 | 
			
		||||
        <p style="font-size: 16px; padding-bottom: 6px; margin-top: 10px; margin-bottom: 5px">
 | 
			
		||||
          <span style="margin-right: 10px">度分</span>
 | 
			
		||||
          <span style="font-size: 12px; margin-bottom: 5px; color: #f16c55"
 | 
			
		||||
            >例如95°10.1702', 49°12.4015'</span
 | 
			
		||||
          >
 | 
			
		||||
        </p>
 | 
			
		||||
        <div class="row">
 | 
			
		||||
          <div class="col" style="flex-direction: column">
 | 
			
		||||
            <div class="row" style="margin-bottom: 15px">
 | 
			
		||||
              <span class="label">经度</span>
 | 
			
		||||
              <input
 | 
			
		||||
                class="input lng-dm-d"
 | 
			
		||||
                style="flex: 1"
 | 
			
		||||
                type="number"
 | 
			
		||||
                min="-180"
 | 
			
		||||
                max="180"
 | 
			
		||||
                value="0"
 | 
			
		||||
                title=""
 | 
			
		||||
              />
 | 
			
		||||
              <span class="label" style="flex: 0 0 14px; margin: 0 10px">度</span>
 | 
			
		||||
              <input
 | 
			
		||||
                class="input lng-dm-m"
 | 
			
		||||
                style="flex: 1"
 | 
			
		||||
                type="number"
 | 
			
		||||
                min="0"
 | 
			
		||||
                max="60"
 | 
			
		||||
                value="0"
 | 
			
		||||
                title=""
 | 
			
		||||
              />
 | 
			
		||||
              <span class="label" style="flex: 0 0 14px; margin: 0 10px">分</span>
 | 
			
		||||
              <span class="top-line"></span>
 | 
			
		||||
            </div>
 | 
			
		||||
            <div class="row">
 | 
			
		||||
              <span class="label">纬度</span>
 | 
			
		||||
              <input
 | 
			
		||||
                class="input lat-dm-d"
 | 
			
		||||
                style="flex: 1"
 | 
			
		||||
                type="number"
 | 
			
		||||
                min="-90"
 | 
			
		||||
                max="90"
 | 
			
		||||
                value="0"
 | 
			
		||||
                title=""
 | 
			
		||||
              />
 | 
			
		||||
              <span class="label" style="flex: 0 0 14px; margin: 0 10px">度</span>
 | 
			
		||||
              <input
 | 
			
		||||
                class="input lat-dm-m"
 | 
			
		||||
                style="flex: 1"
 | 
			
		||||
                type="number"
 | 
			
		||||
                min="0"
 | 
			
		||||
                max="60"
 | 
			
		||||
                value="0"
 | 
			
		||||
                title=""
 | 
			
		||||
              />
 | 
			
		||||
              <span class="label" style="flex: 0 0 14px; margin: 0 10px">分</span>
 | 
			
		||||
              <span class="bottom-line"></span>
 | 
			
		||||
            </div>
 | 
			
		||||
          </div>
 | 
			
		||||
          <div class="col" style="flex: 0 0 24px; margin: 0">
 | 
			
		||||
            <i
 | 
			
		||||
              class="icon-copy-box"
 | 
			
		||||
              title="复制"
 | 
			
		||||
              data-clipboard-action="copy"
 | 
			
		||||
              data-clipboard-target=".input"
 | 
			
		||||
              style="cursor: pointer; position: relative; left: -30px"
 | 
			
		||||
            >
 | 
			
		||||
              <svg class="icon-copy" style="margin: 4px; margin-bottom: 0px">
 | 
			
		||||
                <use xlink:href="#yj-icon-copy"></use>
 | 
			
		||||
              </svg>
 | 
			
		||||
            </i>
 | 
			
		||||
            <button class="convert" style="margin-left: 10px">转 换</button>
 | 
			
		||||
          </div>
 | 
			
		||||
        </div>
 | 
			
		||||
      </div>
 | 
			
		||||
      <div class="div-item item" data-type="2">
 | 
			
		||||
        <span class="custom-divider"></span>
 | 
			
		||||
        <p style="font-size: 16px; padding-bottom: 6px; margin-top: 10px; margin-bottom: 5px">
 | 
			
		||||
          <span style="margin-right: 10px">度分秒</span>
 | 
			
		||||
          <span style="font-size: 12px; margin-bottom: 5px; color: #f16c55"
 | 
			
		||||
            >例如11°18'54.37", 39°13'46.57"</span
 | 
			
		||||
          >
 | 
			
		||||
        </p>
 | 
			
		||||
        <div class="row">
 | 
			
		||||
          <div class="col" style="flex-direction: column">
 | 
			
		||||
            <div class="row" style="margin-bottom: 15px">
 | 
			
		||||
              <span class="label">经度</span>
 | 
			
		||||
              <input
 | 
			
		||||
                class="input lng-dms-d"
 | 
			
		||||
                style="flex: 1"
 | 
			
		||||
                type="number"
 | 
			
		||||
                min="-180"
 | 
			
		||||
                max="180"
 | 
			
		||||
                value="0"
 | 
			
		||||
                title=""
 | 
			
		||||
              />
 | 
			
		||||
              <span class="label" style="flex: 0 0 14px; margin: 0 10px">度</span>
 | 
			
		||||
              <input
 | 
			
		||||
                class="input lng-dms-m"
 | 
			
		||||
                style="flex: 1"
 | 
			
		||||
                type="number"
 | 
			
		||||
                min="0"
 | 
			
		||||
                max="60"
 | 
			
		||||
                value="0"
 | 
			
		||||
                title=""
 | 
			
		||||
              />
 | 
			
		||||
              <span class="label" style="flex: 0 0 14px; margin: 0 10px">分</span>
 | 
			
		||||
              <input
 | 
			
		||||
                class="input lng-dms-s"
 | 
			
		||||
                style="flex: 1"
 | 
			
		||||
                type="number"
 | 
			
		||||
                min="0"
 | 
			
		||||
                max="60"
 | 
			
		||||
                value="0"
 | 
			
		||||
                title=""
 | 
			
		||||
              />
 | 
			
		||||
              <span class="label" style="flex: 0 0 14px; margin: 0 10px">秒</span>
 | 
			
		||||
              <span class="top-line"></span>
 | 
			
		||||
            </div>
 | 
			
		||||
            <div class="row">
 | 
			
		||||
              <span class="label">纬度</span>
 | 
			
		||||
              <input
 | 
			
		||||
                class="input lat-dms-d"
 | 
			
		||||
                style="flex: 1"
 | 
			
		||||
                type="number"
 | 
			
		||||
                min="-90"
 | 
			
		||||
                max="90"
 | 
			
		||||
                value="0"
 | 
			
		||||
                title=""
 | 
			
		||||
              />
 | 
			
		||||
              <span class="label" style="flex: 0 0 14px; margin: 0 10px">度</span>
 | 
			
		||||
              <input
 | 
			
		||||
                class="input lat-dms-m"
 | 
			
		||||
                style="flex: 1"
 | 
			
		||||
                type="number"
 | 
			
		||||
                min="0"
 | 
			
		||||
                max="60"
 | 
			
		||||
                value="0"
 | 
			
		||||
                title=""
 | 
			
		||||
              />
 | 
			
		||||
              <span class="label" style="flex: 0 0 14px; margin: 0 10px">分</span>
 | 
			
		||||
              <input
 | 
			
		||||
                class="input lat-dms-s"
 | 
			
		||||
                style="flex: 1"
 | 
			
		||||
                type="number"
 | 
			
		||||
                min="0"
 | 
			
		||||
                max="60"
 | 
			
		||||
                value="0"
 | 
			
		||||
                title=""
 | 
			
		||||
              />
 | 
			
		||||
              <span class="label" style="flex: 0 0 14px; margin: 0 10px">秒</span>
 | 
			
		||||
              <span class="bottom-line"></span>
 | 
			
		||||
            </div>
 | 
			
		||||
          </div>
 | 
			
		||||
          <div class="col" style="flex: 0 0 24px; margin: 0">
 | 
			
		||||
            <i
 | 
			
		||||
              class="icon-copy-box"
 | 
			
		||||
              title="复制"
 | 
			
		||||
              data-clipboard-action="copy"
 | 
			
		||||
              data-clipboard-target=".input"
 | 
			
		||||
              style="cursor: pointer; position: relative; left: -30px"
 | 
			
		||||
            >
 | 
			
		||||
              <svg class="icon-copy" style="margin: 4px; margin-bottom: 0px">
 | 
			
		||||
                <use xlink:href="#yj-icon-copy"></use>
 | 
			
		||||
              </svg>
 | 
			
		||||
            </i>
 | 
			
		||||
            <button class="convert" style="margin-left: 10px">转 换</button>
 | 
			
		||||
          </div>
 | 
			
		||||
        </div>
 | 
			
		||||
      </div>
 | 
			
		||||
      <span class="custom-divider" style="order: 10; margin-top: 12px"></span>
 | 
			
		||||
    </template>
 | 
			
		||||
    <template #footer>
 | 
			
		||||
      <button @click="close">关闭</button>
 | 
			
		||||
    </template>
 | 
			
		||||
  </Dialog>
 | 
			
		||||
</template>
 | 
			
		||||
 | 
			
		||||
<script setup lang="ts">
 | 
			
		||||
import { ref, reactive } from 'vue'
 | 
			
		||||
import { inject } from 'vue'
 | 
			
		||||
import Dialog from '@/components/dialog/baseDialog.vue'
 | 
			
		||||
import Clipboard from 'clipboard'
 | 
			
		||||
import { ElMessage } from 'element-plus'
 | 
			
		||||
 | 
			
		||||
const baseDialog: any = ref(null)
 | 
			
		||||
const eventBus: any = inject('bus')
 | 
			
		||||
 | 
			
		||||
var status1: any = ref(false)
 | 
			
		||||
var tools: any = reactive([])
 | 
			
		||||
eventBus.on('projConvertDialog', () => {
 | 
			
		||||
  baseDialog.value?.open()
 | 
			
		||||
  if (status1.value) {
 | 
			
		||||
    reset()
 | 
			
		||||
    status1.value = false
 | 
			
		||||
  }
 | 
			
		||||
  status1.value = !status1.value
 | 
			
		||||
  setTimeout(() => {
 | 
			
		||||
    tools = new YJ.Tools(window.earth)
 | 
			
		||||
    tools.projConvert(status1.value, () => {
 | 
			
		||||
      status1.value = false
 | 
			
		||||
    })
 | 
			
		||||
  }, 100)
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
const closeCallBack = (e) => {
 | 
			
		||||
  status1.value = false
 | 
			
		||||
}
 | 
			
		||||
const reset = () => {
 | 
			
		||||
  let contentElm = document
 | 
			
		||||
    .getElementsByClassName('proj-convert')[0]
 | 
			
		||||
    .getElementsByClassName('content')[0]
 | 
			
		||||
  contentElm.getElementsByClassName('lng-dms-d')[0].value = null
 | 
			
		||||
  contentElm.getElementsByClassName('lng-dms-m')[0].value = null
 | 
			
		||||
  contentElm.getElementsByClassName('lng-dms-s')[0].value = null
 | 
			
		||||
  contentElm.getElementsByClassName('lat-dms-d')[0].value = null
 | 
			
		||||
  contentElm.getElementsByClassName('lat-dms-m')[0].value = null
 | 
			
		||||
  contentElm.getElementsByClassName('lat-dms-s')[0].value = null
 | 
			
		||||
  contentElm.getElementsByClassName('lng')[0].value = null
 | 
			
		||||
  contentElm.getElementsByClassName('lat')[0].value = null
 | 
			
		||||
}
 | 
			
		||||
const close = (e) => {
 | 
			
		||||
  baseDialog.value?.close()
 | 
			
		||||
}
 | 
			
		||||
</script>
 | 
			
		||||
 | 
			
		||||
<style scoped lang="scss">
 | 
			
		||||
::v-deep .content > div {
 | 
			
		||||
  display: flex !important;
 | 
			
		||||
  flex-direction: column !important;
 | 
			
		||||
}
 | 
			
		||||
</style>
 | 
			
		||||
@ -0,0 +1,171 @@
 | 
			
		||||
<template>
 | 
			
		||||
  <Dialog
 | 
			
		||||
    ref="baseDialog"
 | 
			
		||||
    class="projection-convert"
 | 
			
		||||
    title="投影转换"
 | 
			
		||||
    left="180px"
 | 
			
		||||
    top="100px"
 | 
			
		||||
    width="634px"
 | 
			
		||||
    :closeCallback="closeCallBack"
 | 
			
		||||
  >
 | 
			
		||||
    <template #content v-if="status1">
 | 
			
		||||
      <span class="custom-divider"></span>
 | 
			
		||||
      <div style="width: 585px; display: flex">
 | 
			
		||||
        <div class="row left" style="flex: 1; margin-bottom: 0">
 | 
			
		||||
          <div
 | 
			
		||||
            style="
 | 
			
		||||
              margin: 10px 0;
 | 
			
		||||
              flex: 1;
 | 
			
		||||
              display: flex;
 | 
			
		||||
              align-items: center;
 | 
			
		||||
              flex: 1;
 | 
			
		||||
              justify-content: space-between;
 | 
			
		||||
            "
 | 
			
		||||
          >
 | 
			
		||||
            <span class="lable-left-line">源坐标</span>
 | 
			
		||||
            <button class="btn pick" style="margin-left: 15px">
 | 
			
		||||
              <svg class="icon-edit"><use xlink:href="#yj-icon-edit"></use></svg>坐标拾取
 | 
			
		||||
            </button>
 | 
			
		||||
            <button
 | 
			
		||||
              class="btn sourceCopy"
 | 
			
		||||
              data-clipboard-action="copy"
 | 
			
		||||
              data-clipboard-target=".input"
 | 
			
		||||
              style="margin-left: 5px"
 | 
			
		||||
            >
 | 
			
		||||
              <svg class="icon-copy"><use xlink:href="#yj-icon-copy"></use></svg>复制
 | 
			
		||||
            </button>
 | 
			
		||||
          </div>
 | 
			
		||||
          <div>
 | 
			
		||||
            <div style="display: flex; margin-bottom: 12px; align-items: center">
 | 
			
		||||
              <span class="label" style="flex: 0 0 60px">椭圆基准</span>
 | 
			
		||||
              <div class="datalist_left"></div>
 | 
			
		||||
            </div>
 | 
			
		||||
            <div style="display: flex; margin-bottom: 12px; align-items: center">
 | 
			
		||||
              <span class="label" style="flex: 0 0 60px">经度(x)</span>
 | 
			
		||||
              <input class="input left-x" type="number" title="" />
 | 
			
		||||
            </div>
 | 
			
		||||
            <div style="display: flex; margin-bottom: 10px; align-items: center">
 | 
			
		||||
              <span class="label" style="flex: 0 0 60px">纬度(y)</span>
 | 
			
		||||
              <input class="input left-y" type="number" title="" />
 | 
			
		||||
            </div>
 | 
			
		||||
          </div>
 | 
			
		||||
        </div>
 | 
			
		||||
        <div
 | 
			
		||||
          style="
 | 
			
		||||
            display: flex;
 | 
			
		||||
            flex-direction: column;
 | 
			
		||||
            justify-content: center;
 | 
			
		||||
            margin: 28px 15px 0 15px;
 | 
			
		||||
          "
 | 
			
		||||
        >
 | 
			
		||||
          <button class="btn convert">
 | 
			
		||||
            <svg-icon name="turn" :size="11" color="rgba(255, 255, 255, 1)"></svg-icon>
 | 
			
		||||
            转换
 | 
			
		||||
          </button>
 | 
			
		||||
        </div>
 | 
			
		||||
        <div class="row right" style="flex: 1; margin-bottom: 0">
 | 
			
		||||
          <div
 | 
			
		||||
            style="
 | 
			
		||||
              margin: 10px 0;
 | 
			
		||||
              height: 32px;
 | 
			
		||||
              display: flex;
 | 
			
		||||
              align-items: center;
 | 
			
		||||
              flex: 1;
 | 
			
		||||
              justify-content: space-between;
 | 
			
		||||
            "
 | 
			
		||||
          >
 | 
			
		||||
            <span class="lable-left-line">目标坐标</span>
 | 
			
		||||
            <button
 | 
			
		||||
              class="btn copy"
 | 
			
		||||
              data-clipboard-action="copy"
 | 
			
		||||
              data-clipboard-target=".input"
 | 
			
		||||
              style="margin-left: 20px"
 | 
			
		||||
            >
 | 
			
		||||
              <svg class="icon-copy"><use xlink:href="#yj-icon-copy"></use></svg>复制
 | 
			
		||||
            </button>
 | 
			
		||||
          </div>
 | 
			
		||||
          <div>
 | 
			
		||||
            <div style="display: flex; margin-bottom: 12px; align-items: center">
 | 
			
		||||
              <span class="label" style="flex: 0 0 60px">椭圆基准</span>
 | 
			
		||||
              <div class="datalist_right"></div>
 | 
			
		||||
            </div>
 | 
			
		||||
            <div style="display: flex; margin-bottom: 12px; align-items: center">
 | 
			
		||||
              <span class="label" style="flex: 0 0 60px">经度(x)</span>
 | 
			
		||||
              <input class="input right-x" readonly="readonly" />
 | 
			
		||||
            </div>
 | 
			
		||||
            <div style="display: flex; margin-bottom: 10px; align-items: center">
 | 
			
		||||
              <span class="label" style="flex: 0 0 60px">纬度(y)</span>
 | 
			
		||||
              <input class="input right-y" readonly="readonly" />
 | 
			
		||||
            </div>
 | 
			
		||||
          </div>
 | 
			
		||||
        </div>
 | 
			
		||||
      </div>
 | 
			
		||||
      <span class="custom-divider"></span>
 | 
			
		||||
    </template>
 | 
			
		||||
    <template #footer>
 | 
			
		||||
      <button @click="close">关闭</button>
 | 
			
		||||
    </template>
 | 
			
		||||
  </Dialog>
 | 
			
		||||
</template>
 | 
			
		||||
 | 
			
		||||
<script setup lang="ts">
 | 
			
		||||
import { ref, reactive } from 'vue'
 | 
			
		||||
import { inject } from 'vue'
 | 
			
		||||
import Dialog from '@/components/dialog/baseDialog.vue'
 | 
			
		||||
import Clipboard from 'clipboard'
 | 
			
		||||
import { ElMessage } from 'element-plus'
 | 
			
		||||
 | 
			
		||||
const baseDialog: any = ref(null)
 | 
			
		||||
const eventBus: any = inject('bus')
 | 
			
		||||
 | 
			
		||||
var status1: any = ref(false)
 | 
			
		||||
var tools: any = reactive([])
 | 
			
		||||
eventBus.on('ProjectionConvertDialog', () => {
 | 
			
		||||
  baseDialog.value?.open()
 | 
			
		||||
  if (status1.value) {
 | 
			
		||||
    reset()
 | 
			
		||||
    status1.value = false
 | 
			
		||||
    tools && tools.projectionConvert(status1.value, () => {})
 | 
			
		||||
  }
 | 
			
		||||
  status1.value = !status1.value
 | 
			
		||||
  setTimeout(() => {
 | 
			
		||||
    tools = new YJ.Tools(window.earth)
 | 
			
		||||
    tools.projectionConvert(status1.value, () => {
 | 
			
		||||
      status1.value = false
 | 
			
		||||
    })
 | 
			
		||||
  }, 100)
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
const closeCallBack = (e) => {
 | 
			
		||||
  status1.value = false
 | 
			
		||||
  tools && tools.projectionConvert(status1.value, () => {})
 | 
			
		||||
}
 | 
			
		||||
const reset = () => {
 | 
			
		||||
  let contentElm = document
 | 
			
		||||
    .getElementsByClassName('projection-convert')[0]
 | 
			
		||||
    .getElementsByClassName('content')[0]
 | 
			
		||||
  contentElm.getElementsByClassName('left-x')[0].value = null
 | 
			
		||||
  contentElm.getElementsByClassName('left-y')[0].value = null
 | 
			
		||||
  contentElm.getElementsByClassName('right-x')[0].value = null
 | 
			
		||||
  contentElm.getElementsByClassName('right-y')[0].value = null
 | 
			
		||||
}
 | 
			
		||||
const close = (e) => {
 | 
			
		||||
  baseDialog.value?.close()
 | 
			
		||||
}
 | 
			
		||||
</script>
 | 
			
		||||
 | 
			
		||||
<style scoped lang="scss">
 | 
			
		||||
::v-deep .content > div {
 | 
			
		||||
  display: flex !important;
 | 
			
		||||
  flex-direction: column !important;
 | 
			
		||||
}
 | 
			
		||||
::v-deep .content .cy_datalist input {
 | 
			
		||||
  background: rgba(var(--color-sdk-base-rgb), 0.2) !important;
 | 
			
		||||
  border: unset;
 | 
			
		||||
}
 | 
			
		||||
::v-deep .content input[type='number'] {
 | 
			
		||||
  font-size: 16px !important;
 | 
			
		||||
  // font-weight: 700 !important;
 | 
			
		||||
  color: var(--color-sdk-auxiliary-public) !important;
 | 
			
		||||
}
 | 
			
		||||
</style>
 | 
			
		||||
@ -1,4 +1,4 @@
 | 
			
		||||
<!-- <template>
 | 
			
		||||
<template>
 | 
			
		||||
  <Dialog ref="baseDialog" title="地形开挖" left="180px" top="100px" :closeCallback="closeCallBack">
 | 
			
		||||
    <template #content>
 | 
			
		||||
      <span class="custom-divider"></span>
 | 
			
		||||
@ -43,7 +43,7 @@
 | 
			
		||||
      </div>
 | 
			
		||||
    </template>
 | 
			
		||||
    <template #footer>
 | 
			
		||||
      <button @click="close">取消</button>
 | 
			
		||||
      <button @click="close">关闭</button>
 | 
			
		||||
    </template>
 | 
			
		||||
  </Dialog>
 | 
			
		||||
</template>
 | 
			
		||||
@ -62,7 +62,7 @@ var excavation: any = reactive([])
 | 
			
		||||
eventBus.on('terrainExcavationDialog', () => {
 | 
			
		||||
  baseDialog.value?.open()
 | 
			
		||||
 | 
			
		||||
  excavation = new (window as any).YJ.Analysis.TerrainExcavation(this.sdk, { height: 10 })
 | 
			
		||||
  excavation = new (window as any).YJ.Analysis.TerrainExcavation(window.earth, { height: 10 })
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
const changeHeight = () => {
 | 
			
		||||
@ -76,7 +76,9 @@ const heightInput = () => {
 | 
			
		||||
    height.value = dom.max * 1
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
const closeCallBack = (e) => {}
 | 
			
		||||
const closeCallBack = (e) => {
 | 
			
		||||
  height.value = 10
 | 
			
		||||
}
 | 
			
		||||
const close = (e) => {
 | 
			
		||||
  baseDialog.value?.close()
 | 
			
		||||
}
 | 
			
		||||
@ -88,4 +90,4 @@ const clear = (e) => {
 | 
			
		||||
}
 | 
			
		||||
</script>
 | 
			
		||||
 | 
			
		||||
<style scoped lang="scss"></style> -->
 | 
			
		||||
<style scoped lang="scss"></style>
 | 
			
		||||
 | 
			
		||||
@ -113,7 +113,7 @@ eventBus.on('viewShedDialog', () => {
 | 
			
		||||
    e_horizontalViewAngle.removeEventListener('change', changeFun)
 | 
			
		||||
    e_horizontalViewAngle.addEventListener('input', inputFun)
 | 
			
		||||
    e_horizontalViewAngle.addEventListener('change', changeFun)
 | 
			
		||||
  })
 | 
			
		||||
  }, 10)
 | 
			
		||||
})
 | 
			
		||||
function inputFun() {
 | 
			
		||||
  let contentElm = document.getElementsByClassName('view-shed')[0]
 | 
			
		||||
 | 
			
		||||
@ -32,7 +32,11 @@
 | 
			
		||||
  <!-- <FlyRoam ref="FlyRoam"></FlyRoam> -->
 | 
			
		||||
  <CoorLocation ref="CoorLocation"></CoorLocation>
 | 
			
		||||
  <ScreenShot ref="ScreenShot"></ScreenShot>
 | 
			
		||||
  <!-- <TerrainExcavation ref="TerrainExcavation"></TerrainExcavation> -->
 | 
			
		||||
  <TerrainExcavation ref="TerrainExcavation"></TerrainExcavation>
 | 
			
		||||
  <ProjConvert ref="ProjConvert"></ProjConvert>
 | 
			
		||||
  <ProjectionConvert ref="ProjectionConvert"></ProjectionConvert>
 | 
			
		||||
  <GoodsSearchCircle ref="GoodsSearchCircle"></GoodsSearchCircle>
 | 
			
		||||
  <GoodsSearchPolgon ref="GoodsSearchPolgon"></GoodsSearchPolgon>
 | 
			
		||||
</template>
 | 
			
		||||
 | 
			
		||||
<script setup lang="ts">
 | 
			
		||||
@ -66,6 +70,10 @@ import FlyRoam from '../components/propertyBox/FlyRoam.vue'
 | 
			
		||||
import CoorLocation from '../components/propertyBox/CoorLocation.vue'
 | 
			
		||||
import ScreenShot from '../components/propertyBox/ScreenShot.vue'
 | 
			
		||||
import TerrainExcavation from '../components/propertyBox/TerrainExcavation.vue'
 | 
			
		||||
import ProjConvert from '../components/propertyBox/ProjConvert.vue'
 | 
			
		||||
import ProjectionConvert from '../components/propertyBox/ProjectionConvert.vue'
 | 
			
		||||
import GoodsSearchCircle from '../components/propertyBox/GoodsSearchCircle.vue'
 | 
			
		||||
import GoodsSearchPolgon from '../components/propertyBox/GoodsSearchPolgon.vue'
 | 
			
		||||
 | 
			
		||||
import { GisApi } from '@/api/gisApi'
 | 
			
		||||
 | 
			
		||||
@ -123,7 +131,7 @@ eventBus.on('openDialog', async (sourceType: any, id: any) => {
 | 
			
		||||
      currentComponent.value = circleObject
 | 
			
		||||
      await nextTick()
 | 
			
		||||
      dynamicComponentRef.value?.open(id, 'circle')
 | 
			
		||||
      break;
 | 
			
		||||
      break
 | 
			
		||||
    case 'rectangle':
 | 
			
		||||
      currentComponent.value = polygonObject
 | 
			
		||||
      await nextTick()
 | 
			
		||||
 | 
			
		||||
		Reference in New Issue
	
	Block a user