Browse Source

粤政图 协同标绘功能

Hwf 4 tháng trước cách đây
mục cha
commit
feaa21f968

+ 24 - 0
src/utils/index.ts

@@ -401,6 +401,30 @@ export const hexToRgba = (hex, alpha) => {
   return `rgba(${r}, ${g}, ${b}, ${alpha || 1})`;
 };
 
+export const rgbToRgba = (rgbString, alpha) => {
+  if (!rgbString) return '';
+  // 去掉字符串两端的空格
+  rgbString = rgbString.trim();
+
+  // 使用正则表达式匹配 rgb 格式的数字部分
+  const rgbMatch = rgbString.match(/\d+/g);
+
+  // 如果没有匹配到 rgb 格式,返回 null
+  if (!rgbMatch || rgbMatch.length !== 3) {
+    return null;
+  }
+
+  // 将匹配到的数字部分转换为整数
+  const r = parseInt(rgbMatch[0], 10);
+  const g = parseInt(rgbMatch[1], 10);
+  const b = parseInt(rgbMatch[2], 10);
+
+  // 拼接 rgba 字符串
+  const rgbaString = `rgba(${r}, ${g}, ${b}, ${alpha})`;
+
+  return rgbaString;
+};
+
 export const initDrag = (el, scaleX = 1, scaleY = 1) => {
   if (!el) return;
   el.style.position = 'fixed';

+ 145 - 29
src/utils/olMap/olMap.ts

@@ -33,7 +33,7 @@ import Overlay from 'ol/Overlay';
 import { Draw, Select } from 'ol/interaction';
 import { click } from 'ol/events/condition';
 import Circle from 'ol/geom/Circle';
-import { deepClone, hexToRgba, initDrag } from '@/utils';
+import { deepClone, getRgba, hexToRgba, initDrag, rgbToRgba } from '@/utils';
 import { createBox } from 'ol/interaction/Draw';
 import * as turf from '@turf/turf';
 import { nanoid } from 'nanoid';
@@ -321,6 +321,7 @@ export class olMap {
       marker: 'Point',
       text: 'Point'
     };
+    const data = getRgba(newOptions.color);
     let geometryFunction = null;
     if (newOptions.graphicsType === 'rectangle') {
       // 绘制矩形的方法
@@ -341,11 +342,12 @@ export class olMap {
       } else {
         this.drawOptions = {
           type: newOptions.graphicsType,
-          strokeColor: newOptions.color,
+          title: newOptions.title,
+          strokeColor: !!data.color ? data.color : newOptions.color,
           strokeOpacity: 1,
           strokeWeight: 1,
-          fillColor: newOptions.color,
-          fillOpacity: newOptions.drawType === '1' ? '0' : '0.5',
+          fillColor: data.color,
+          fillOpacity: data.opacity,
           strokeStyle: 'solid'
         };
         if (newOptions.graphicsType === 'marker') {
@@ -357,11 +359,11 @@ export class olMap {
         // 创建绘制交互
         let style = new Style({
           stroke: new Stroke({
-            color: hexToRgba(this.drawOptions.strokeColor, this.drawOptions.strokeOpacity),
+            color: rgbToRgba(this.drawOptions.strokeColor, this.drawOptions.strokeOpacity),
             width: this.drawOptions.strokeWeight
           }),
           fill: new Fill({
-            color: hexToRgba(this.drawOptions.fillColor, this.drawOptions.fillOpacity)
+            color: rgbToRgba(this.drawOptions.fillColor, this.drawOptions.fillOpacity)
           })
         });
         this.drawTool = new Draw({
@@ -575,27 +577,34 @@ export class olMap {
       });
       // 设置自定义属性
       feature.set('pointer', true);
-      // 定义样式
-      const style = new Style({
-        image: new Icon({
-          anchor: [0.5, 0.5],
-          scale: 0.146,
-          anchorXUnits: 'fraction',
-          anchorYUnits: 'pixels',
-          src: point.icon
-        }),
-        text: new Text({
-          text: point.name,
-          fill: new Fill({
-            color: '#000'
+      const img = new Image();
+      img.onload = () => {
+        // 图片加载完成后,可以访问其 width 和 height 属性
+        const width = img.width;
+        const height = img.height;
+        const style = new Style({
+          image: new Icon({
+            anchor: [0.5, 0.5],
+            anchorXUnits: 'fraction',
+            anchorYUnits: 'pixels',
+            src: point.icon,
+            size: [width, height],
+            scale: !!point.size[0] ? point.size[0] / width : 1
           }),
-          stroke: new Stroke({
-            color: '#fff',
-            width: 3
+          text: new Text({
+            text: point.name,
+            fill: new Fill({
+              color: '#000'
+            }),
+            stroke: new Stroke({
+              color: '#fff',
+              width: 3
+            })
           })
-        })
-      });
-      feature.setStyle(style);
+        });
+        features.setStyle(style);
+      };
+      img.src = point.icon; // 设置图片的 URL,触发加载
       features.push(feature);
       this.markers.push(point);
     });
@@ -904,11 +913,11 @@ export class olMap {
     feature.setStyle(
       new Style({
         stroke: new Stroke({
-          color: hexToRgba(data.strokeColor, data.strokeOpacity),
+          color: rgbToRgba(data.strokeColor, data.strokeOpacity),
           width: data.strokeWeight
         }),
         fill: new Fill({
-          color: hexToRgba(data.fillColor, data.fillOpacity)
+          color: rgbToRgba(data.fillColor, data.fillOpacity)
         })
       })
     );
@@ -921,11 +930,28 @@ export class olMap {
     feature.setStyle(
       new Style({
         stroke: new Stroke({
-          color: hexToRgba(data.strokeColor, data.strokeOpacity),
+          color: rgbToRgba(data.strokeColor, data.strokeOpacity),
           width: data.strokeWeight
         }),
         fill: new Fill({
-          color: hexToRgba(data.fillColor, data.fillOpacity)
+          color: rgbToRgba(data.fillColor, data.fillOpacity)
+        })
+      })
+    );
+    this.drawVector.getSource().addFeature(feature);
+    return feature;
+  }
+  createLineString(data) {
+    const lineString = new LineString(data.path);
+    const feature = new Feature(lineString);
+    feature.setStyle(
+      new Style({
+        stroke: new Stroke({
+          color: rgbToRgba(data.strokeColor, data.strokeOpacity),
+          width: data.strokeWeight
+        }),
+        fill: new Fill({
+          color: rgbToRgba(data.fillColor, data.fillOpacity)
         })
       })
     );
@@ -1021,6 +1047,96 @@ export class olMap {
     const geo = this.carFeature.getGeometry().clone();
     this.carFeature.setGeometry(geo);
   }
+  drawData(data) {
+    const res = [];
+    data.forEach((item) => {
+      let graphic;
+      if (['rectangle', 'polygon', 'anyLine'].includes(item.type)) {
+        graphic = this.createPolygon(item);
+        graphic.set('id', item.id);
+        res.push(graphic);
+      } else if (item.type === 'circle') {
+        graphic = this.createCircle(item);
+        graphic.set('id', item.id);
+        res.push(graphic);
+      } else if (item.type === 'straightLine') {
+        graphic = this.createLineString(item);
+        graphic.set('id', item.id);
+        res.push(graphic);
+      } else if (item.type === 'text') {
+        const { text } = this.addText(item);
+        res.push(text);
+      } else if (item.type === 'measureArea') {
+        graphic = this.createPolygon(item);
+        graphic.set('id', item.id);
+        const style = new Style({
+          stroke: new Stroke({
+            color: rgbToRgba(item.strokeColor, item.strokeOpacity),
+            width: item.strokeWeight
+          }),
+          fill: new Fill({
+            color: rgbToRgba(item.fillColor, item.fillOpacity)
+          }),
+          text: new Text({
+            text: '区域面积' + item.area.toFixed(2) + '平方米',
+            font: '14px Calibri,sans-serif',
+            fill: new Fill({ color: '#000' }),
+            stroke: new Stroke({
+              color: '#fff',
+              width: 3
+            }),
+            overflow: true
+          })
+        });
+
+        graphic.setStyle(style);
+        res.push(graphic);
+      } else if (item.type === 'marker') {
+        // 创建标注点
+        const marker = new Feature({
+          // 必须是数字类型,字符串不识别
+          geometry: new Point([item.longitude, item.latitude]),
+          // name: item.name,
+          // icon: item.icon,
+          // imageHover: item.imageHover,
+          // size: item.size,
+          pointer: true
+        });
+        marker.set('id', item.id);
+        const img = new Image();
+        img.onload = () => {
+          // 图片加载完成后,可以访问其 width 和 height 属性
+          const width = img.width;
+          const height = img.height;
+          const style = new Style({
+            image: new Icon({
+              anchor: [0.5, 0.5],
+              anchorXUnits: 'fraction',
+              anchorYUnits: 'pixels',
+              src: item.icon,
+              size: [width, height],
+              scale: !!item.size[0] ? item.size[0] / width : 1
+            }),
+            text: new Text({
+              text: item.name,
+              fill: new Fill({
+                color: '#000'
+              }),
+              stroke: new Stroke({
+                color: '#fff',
+                width: 3
+              })
+            })
+          });
+          marker.setStyle(style);
+        };
+        img.src = item.icon; // 设置图片的 URL,触发加载
+        this.drawVector.getSource().addFeature(marker);
+        res.push(marker);
+      }
+    });
+    return res;
+  }
   getVectorLayer() {
     return this.vectorLayer;
   }

+ 28 - 29
src/views/globalMap/RightMenu/OnlinePlotting/index.vue

@@ -218,8 +218,6 @@ import { showSuccessMsg } from '@/utils/notification';
 import * as turf from '@turf/turf';
 import Style from 'ol/style/Style';
 import Icon from 'ol/style/Icon';
-import { Fill, Stroke } from 'ol/style';
-import Text from 'ol/style/Text';
 
 const props = defineProps({
   activeMap: String
@@ -568,41 +566,35 @@ const initDrawMethod = (options) => {
               anchorYUnits: 'fraction',
               size: [width, height],
               scale: !!options.size[0] ? options.size[0] / width : 1
-            }),
-            // text: new Text({
-            //   text: data.title, // 使用属性中的值作为文本
-            //   font: '14px sans-serif',
-            //   fill: new Fill({
-            //     color: '#ffff'
-            //   })
-            // })
+            })
           });
           feature.setStyle(style);
-          const position = geometry.getCoordinates();
-          data.lnglat = position;
-          data.latitude = position[0];
-          data.longitude = position[1];
-          data.icon = data.iconName;
-          data.image = data.iconName;
-          data.imageHover = data.iconName;
-          data.visible = true;
         };
+        const position = geometry.getCoordinates();
+        data.lnglat = position;
+        data.longitude = position[0];
+        data.latitude = position[1];
+        data.icon = data.iconName;
+        data.image = data.iconName;
+        data.imageHover = data.iconName;
+        data.visible = true;
         img.src = options.icon; // 设置图片的 URL,触发加载
       } else {
         if (options.type == 'circle') {
-          data.center = [geometry.getCenter().lng, geometry.getCenter().lat];
+          data.center = geometry.getCenter();
           data.radius = geometry.getRadius();
         } else {
           const coordinates = geometry.getCoordinates();
-          const pathArr = coordinates[0];
-          data.path = pathArr;
+          if (['rectangle', 'polygon', 'anyLine', 'measureArea'].includes(options.type)) {
+            data.path = coordinates[0];
+          } else {
+            data.path = coordinates;
+          }
         }
       }
       if (options.type == 'measureArea') {
         // 计算区域面积
         const area = turf.area(turf.polygon([data.path]));
-
-
         // const text = new AMap.Text({
         //   position: data.path[data.path.length - 1],
         //   text: '区域面积' + area + '平方米',
@@ -667,6 +659,13 @@ const sendWebSocket = (data) => {
       visible: '1'
     })
   );
+  console.log('fs', {
+    operation: 'add', // 必填
+    id: data.id,
+    name: data.title, // 必填
+    content: JSON.stringify(data), // 必填
+    visible: '1'
+  });
 };
 // 图形右击事件
 let rightClickObj;
@@ -917,15 +916,15 @@ const handleSendForm = () => {
   if (!form.value.pattern_name) {
     return proxy?.$modal.msgWarning('请填写预案名称');
   }
-  // webSock = createWebSocket('X_cBqh0q1GUVhTOmS5c8w', getWebSocketData);
-  // patternId.value = 'X_cBqh0q1GUVhTOmS5c8w';
-  createCollaboration(form.value).then(() => {
-    patternId.value = form.value.pattern_id;
-    webSock = createWebSocket(form.value.pattern_id, getWebSocketData);
+  webSock = createWebSocket('uhvw60vX7MpeWSWcXqK8S', getWebSocketData);
+  patternId.value = 'uhvw60vX7MpeWSWcXqK8S';
+  // createCollaboration(form.value).then(() => {
+  //   patternId.value = form.value.pattern_id;
+  //   webSock = createWebSocket(form.value.pattern_id, getWebSocketData);
     showForm.value = false;
     collaboration.value = true;
     proxy?.$modal.msgSuccess('开启协同标绘成功');
-  });
+  // });
 };
 const handleShowDialog = () => {
   editData.value = {