wujingjing
2025-02-26 08c6ecf506bfc7003894775fe57d98d9b11f3d9e
src/components/chat/chatComponents/summaryCom/components/recordSetTable/map/panelTool/ThemeControl.vue
@@ -74,94 +74,25 @@
<script setup lang="ts" name="ThemeControl">
import type { ElTree } from 'element-plus';
import { chunk } from 'lodash-es';
import Circle from 'ol/style/Circle';
import Style from 'ol/style/Style';
import type { PropType } from 'vue';
import { computed, ref, watch } from 'vue';
import { switchMapTheme } from '/@/api/map';
import type { OLMap } from '/@/model/map/OLMap';
import { formatDate } from '/@/utils/formatTime';
import { travelTree } from '/@/utils/util';
import Fill from 'ol/style/Fill';
import Stroke from 'ol/style/Stroke';
import { Text } from 'ol/style';
import { ElLoadingService } from 'element-plus';
const props = defineProps(['olMap']);
const props = defineProps({
   olMap: {
      type: Object as PropType<OLMap>,
      required: true,
   },
});
const emit = defineEmits(['close']);
const defaultProps = {
   children: 'children',
   label: 'title',
};
const closeClick = () => {
   emit('close');
};
const checkTreeRef = ref<InstanceType<typeof ElTree>>();
const parseLegends = (legends) => {
   const result = legends.map((item) => {
      const isEqual = item.operate === '=';
      const result = {
         ...item,
         legend: item.legend.map((legendItem, index, array) => {
            const preItem = array[index - 1];
            let label = '';
            if (isEqual) {
               label = legendItem.value;
            } else if (preItem) {
               label = `>${preItem.value}且${item.operate}${legendItem.value}`;
            } else {
               label = `${item.operate}${legendItem.value}`;
            }
            return {
               ...legendItem,
               label: label,
            };
         }),
      };
      result.legend.push({
         style: item.default,
         value: '',
         label: result.legend.length == 0 ? '默认' : `>${item.legend[item.legend.length - 1].value}`,
      });
      return result;
   });
   return result;
};
let isHumanCheckTrigger = false;
const handleCheck = (data: any, node: any) => {
   const checkedKeys = node.checkedKeys;
   isHumanCheckTrigger = true;
   // 取消分组中旧的选项
   const excludeKeys = [];
   for (const themeGroup of themeInfo.value) {
      // 原来有多少个设置的
      const originSet = themeGroup.children.filter((item) => item.isSet);
      // 现在有多少个设置的
      const newSet = themeGroup.children.filter((item) => checkedKeys.includes(item.id));
      if (originSet.length === 1 && newSet.length === 2) {
         originSet[0].isSet = false;
         excludeKeys.push(originSet[0].id);
      }
   }
   const realCheckedKeys = checkedKeys.filter((key) => !excludeKeys.includes(key));
   travelTree(themeInfo.value, (theme, index, array, parent) => {
      if (theme.type === 'theme') {
         const id = theme.id;
         if (!realCheckedKeys.includes(id)) {
            theme.isSet = false;
         } else {
            theme.isSet = true;
         }
      }
   });
   checkTreeRef.value?.setCheckedKeys(realCheckedKeys);
};
const handleNodeClick = () => {};
const themeInfo = computed(() => {
   const info = (props.olMap as OLMap).themeInfo.value;
   // info.push({
@@ -247,170 +178,12 @@
   return result;
});
const styleMap: Record<string, Record<string, Style>> = {
   junction: {},
   pipe: {},
   polygon: {},
};
const maxResolution = 1;
const getText = function (feature, resolution) {
   const oname = feature.get('oname');
   let text = `first-${oname[0]}`;
   if (resolution > maxResolution) {
      text = '';
   }
   // else if (type == 'hide') {
   //    text = '';
   // } else if (type == 'shorten') {
   //    text = text.trunc(12);
   // } else if (type == 'wrap' && (!dom.placement || dom.placement.value != 'line')) {
   //    text = stringDivider(text, 16, '\n');
   // }
   return text;
};
const createTextStyle = (feature, resolution) => {
   return new Style({
      text: new Text({
         text: getText(feature, resolution),
         font: '14px Arial',
         fill: new Fill({ color: '#000' }),
         stroke: new Stroke({ color: '#fff', width: 2 }),
         offsetX: 10, // 文字相对于几何中心的水平偏移
         offsetY: 20, // 文字相对于几何中心的垂直偏移
      }),
   });
};
const legendList = ref([]);
const changeTheme = async (themeId: string) => {
   const loadingInstance = ElLoadingService({
      text: '加载主题中...',
      target: '.layout-parent',
   });
   const res = await switchMapTheme({
      theme_id: themeId,
      time: formatDate(new Date()),
   }).finally(() => {
      loadingInstance.close();
   });
   // 加入主题之后的样式函数
   const themeLayerStyleFunc = (feature, resolution) => {
      const otype = feature.get('otype');
      const oname = feature.get('oname');
      // oname 映射样式
      const onameStyleMap = res?.[`O_${otype}`] ?? {};
      const themeStyles = res?.styles ?? [];
      const styleIndex = onameStyleMap[oname]?.style_id;
      const themeStyle = styleIndex == null ? null : themeStyles[styleIndex];
      // if(themeStyle){
      // }
      const shape = feature.getGeometry().getType();
      const styles = [];
      switch (shape) {
         case 'Point':
            const pSize = themeStyle?.PSIZE ?? feature.get('psize');
            const pcolor = themeStyle?.PCOLOR ?? feature.get('pcolor');
            const pStyle = themeStyle?.PSTYLE ?? feature.get('pstyle');
            const pointStyle = props.olMap?.getPointStyles({
               size: pSize,
               color: pcolor,
               style: pStyle,
            });
            pointStyle && styles.push(pointStyle);
            break;
         case 'LineString':
            const lSize = themeStyle?.LSIZE ?? feature.get('lsize');
            const lColor = themeStyle?.LCOLOR ?? feature.get('lcolor');
            const lStyle = themeStyle?.LSTYLE ?? feature.get('lstyle');
            const pSize1 = themeStyle?.PSIZE ?? feature.get('psize');
            const pcolor1 = themeStyle?.PCOLOR ?? feature.get('pcolor');
            const pStyle1 = themeStyle?.PSTYLE ?? feature.get('pstyle');
            const lineStyle = props.olMap?.getLineStyles({
               lsize: lSize,
               lcolor: lColor,
               lstyle: lStyle,
               psize: pSize1,
               pcolor: pcolor1,
               pstyle: pStyle1,
            });
            lineStyle && styles.push(...lineStyle);
            break;
         case 'Polygon':
            const pColor = themeStyle?.PCOLOR ?? feature.get('pcolor');
            const lSize1 = themeStyle?.LSIZE ?? feature.get('lsize');
            const lColor1 = themeStyle?.LCOLOR ?? feature.get('lcolor');
            const lstyle1 = themeStyle?.LSTYLE ?? feature.get('lstyle');
            const polygonStyle = props.olMap?.getPolygonStyles({
               pcolor: pColor,
               lsize: lSize1,
               lcolor: lColor1,
               lstyle: lstyle1,
            });
            polygonStyle && styles.push(...polygonStyle);
            break;
         default:
            break;
      }
      // switch (otype) {
      //    case 'WDM_JUNCTIONS':
      //       const textStyle = createTextStyle(feature, resolution);
      //       styles.push(textStyle);
      //    case 'WDM_PIPES':
      //       break;
      // }
      //#region ====================== 添加标注 ======================
      const tString = themeStyle?.TSTRING ?? feature.get('tstring');
      const tStringStyle = props.olMap?.getLabelStyles({
         textContent: tString,
         resolution,
      });
      tStringStyle && styles.push(tStringStyle);
      //#endregion
      return styles;
   };
   const allLayers = props.olMap.getAllLayers();
   for (const item of allLayers) {
      if (props.olMap?.unsupportedLayers.includes(item.id)) {
         continue;
      }
      item.model.setStyle(themeLayerStyleFunc);
   }
   return res?.legends ?? [];
};
const legendList = computed(() => {
   return props.olMap.legendList.value;
});
const handleThemeChange = async (val, themeGroup) => {
   const allIds = [];
   for (const item of themeInfo.value) {
      if (item.activeTheme) {
         allIds.push(item.activeTheme);
      }
   }
   const ids = allIds.join(',');
   if (!ids) {
      const allLayers = props.olMap.getAllLayerModels();
      for (const item of allLayers) {
         const originStyle = item.get('originStyle');
         originStyle && item.setStyle(originStyle);
      }
      return;
   }
   const legends = await changeTheme(ids);
   legendList.value = parseLegends(legends);
   props.olMap.changeTheme(val);
};
const cancelTheme = (themeId: string) => {
   themeInfo.value.find((item) => item.id === themeId).activeTheme = null;