소스 검색

开个头

DESKTOP-6LTVLN7\Liumouren 2 일 전
부모
커밋
1a98445110
5개의 변경된 파일892개의 추가작업 그리고 12개의 파일을 삭제
  1. 1 0
      public/static/config/config.js
  2. 12 0
      src/api/skszk.js
  3. 17 0
      src/utils/request.js
  4. 855 12
      src/views/skszk/Example.vue
  5. 7 0
      vue.config.js

+ 1 - 0
public/static/config/config.js

@@ -4,6 +4,7 @@ let systemConfig = {
         userName: "user002",
         password: "Yysz@1234002"
     },
+    baseServicerPath: "/oneMap",
     // oauth地址
     oauthServiceUrlOrigin: "http://121.43.55.7:10086/",
     // oauth地址

+ 12 - 0
src/api/skszk.js

@@ -0,0 +1,12 @@
+import {
+    postBody
+} from '../utils/request'
+
+// 拓扑计算
+const topology = (params) => {
+    return postBody(systemConfig.baseServicerPath + '/topology/geoJsonToGeoJson', params)
+}
+
+export default {
+    topology,
+}

+ 17 - 0
src/utils/request.js

@@ -143,6 +143,22 @@ function postform(url, data) {
     })
   })
 }
+function postBody(url, data) {
+  return new Promise((resolve, reject) => {
+    service({
+      method: 'POST',
+      url,
+      data: data,
+      headers: {
+        'Content-Type': 'application/json;'
+      }
+    }).then(res => {
+      resolve(res.data)
+    }).catch(err => {
+      reject(err)
+    })
+  })
+}
 
 function put(url, data) {
   return new Promise((resolve, reject) => {
@@ -280,6 +296,7 @@ export {
   put,
   putform,
   postform,
+  postBody,
   delform,
   postFile,
   getFile,

+ 855 - 12
src/views/skszk/Example.vue

@@ -1,27 +1,870 @@
 <template>
-    <div class="example">
-        skszk example
+  <!-- 时空算子库 -->
+  <div class="example">
+    <div class="toolbar">
+      <div
+        class="tool-item"
+        @click="activateDraw('point')"
+        :class="{ active: currentTool === 'point' }"
+      >
+        绘制点
+      </div>
+      <div
+        class="tool-item"
+        @click="activateDraw('polyline')"
+        :class="{ active: currentTool === 'polyline' }"
+      >
+        绘制线
+      </div>
+      <div
+        class="tool-item"
+        @click="activateDraw('polygon')"
+        :class="{ active: currentTool === 'polygon' }"
+      >
+        绘制面
+      </div>
+      <div class="tool-item" @click="startHoleDrawing" :class="{ active: isDrawingHole }">
+        绘制镂空
+      </div>
+      <div class="tool-item" @click="clearAll">清除所有</div>
     </div>
+    <div id="skysceneryContainer"></div>
+  </div>
 </template>
 
 <script>
+import skszk from "../../api/skszk";
+// 需要开发出一个时空算子库的示例页面:需要能绘制点线面的工具,且能包装绘制的几何对象传入到后台接口中
 export default {
-    name: "",
-    data() {
-        return {
+  name: "SkszkExample",
+  data() {
+    return {
+      globalvar: systemConfig.example,
+      currentTool: null,
+      drawingMode: null,
+      handler: null,
+      drawnEntities: [],
+      geometries: [], // 存储绘制的几何对象
+      // 绘制状态相关
+      currentEntity: null, // 当前正在绘制的实体
+      currentPositions: [], // 当前正在绘制的位置数组
+      isDrawingHole: false, // 是否正在绘制镂空
+      currentPolygonEntity: null, // 当前要添加镂空的多边形实体
+      currentPolygonGeometry: null, // 当前要添加镂空的多边形几何对象
+      tempEntity: null, // 临时预览实体
+    };
+  },
+  mounted() {
+    window.SkySceneryConfig = {};
+    this.loadScripts();
+  },
+  methods: {
+    loadScripts() {
+      let that = this;
+      SkySceneryConfig = {
+        authUrl: systemConfig.oauthServiceUrlOrigin,
+        token: localStorage.getItem("token"),
+      };
+      this.addScripts(this.globalvar.scriptObj.main).then(function () {
+        let arr = that.globalvar.scriptObj.plugins.map(function (src) {
+          return that.addScripts(src);
+        });
+        Promise.all(arr).then(function () {
+          that.creatMap();
+        });
+      });
+    },
+    addScripts(src) {
+      return new Promise((resolve, reject) => {
+        // 创建一个新的script标签
+        var script = document.createElement("script");
+        // 设置script标签的src属性为要引入的JavaScript文件的URL
+        script.src = src;
+        // 将script标签添加到页面的head部分或者其他合适的位置
+        document.head.appendChild(script);
+        if (script.readyState) {
+          // IE
+          script.onreadystatechange = function () {
+            if (script.readyState === "loaded" || script.readyState === "complete") {
+              script.onreadystatechange = null;
+              resolve();
+            }
+          };
+        } else {
+          // 其他浏览器
+          script.onload = function () {
+            resolve();
+          };
+        }
+      });
+    },
+    creatMap() {
+      window.viewer = new SkyScenery.Viewer("skysceneryContainer", {
+        animation: false, //是否创建动画小器件,左下角仪表
+        baseLayerPicker: false, //是否显示图层选择器
+        imageryProvider: new SkyScenery.SingleTileImageryProvider({
+          url: (function createColorCanvas(color) {
+            var width = 1,
+              height = 1;
+            var canvas = document.createElement("canvas");
+            canvas.width = width;
+            canvas.height = height;
+            var ctx = canvas.getContext("2d");
+            ctx.fillStyle = color;
+            ctx.fillRect(0, 0, width, height);
+            return canvas.toDataURL();
+          })("#ffffff00"),
+          rectangle: SkyScenery.Rectangle.fromDegrees(-180.0, -90.0, 180.0, 90.0),
+        }),
+        fullscreenButton: false, //是否显示全屏按钮
+        geocoder: false, //是否显示geocoder小器件,右上角查询按钮
+        homeButton: false, //是否显示Home按钮
+        infoBox: false, //是否显示信息框
+        sceneModePicker: false, //是否显示3D/2D选择器
+        selectionIndicator: false, //是否显示选取指示器组件
+        timeline: false, //是否显示时间轴
+        navigationHelpButton: false, //是否显示右上角的帮助按钮
+        scene3DOnly: true, //如果设置为true,则所有几何图形以3D模式绘制以节约GPU资源
+        shouldAnimate: false, //是否自动播放
+        // 性能优化配置
+        requestRenderMode: true,
+        maximumRenderTimeChange: Infinity,
+        preserveDrawingBuffer: false,
+        useBrowserRecommendedResolution: true,
+      });
+
+      // 添加地图服务
+      viewer.imageryLayers.addImageryProvider(
+        new SkyScenery.ArcGisMapServerImageryProvider({
+          url:
+            "https://szlszxdt.qpservice.org.cn/internal_map/?servertype=shmap_blue_web&proxyToken=" +
+            SkySceneryConfig.token,
+          enablePickFeatures: false, // 禁用要素拾取功能以提高性能
+        })
+      );
+
+      // 定位
+      viewer.camera.setView({
+        destination: SkyScenery.Cartesian3.fromDegrees(121.1, 31, 30000.0), // 设置位置
+        orientation: {
+          heading: SkyScenery.Math.toRadians(0.0), // 方向
+          pitch: SkyScenery.Math.toRadians(-90.0), // 倾斜角度
+          roll: 0,
+        },
+      });
+
+      // 初始化绘制处理器
+      this.initDrawHandler();
+    },
+
+    // 初始化绘制处理器
+    initDrawHandler() {
+      // 创建绘制处理器
+      this.handler = new SkyScenery.ScreenSpaceEventHandler(viewer.canvas);
+    },
+
+    // 激活绘制工具
+    activateDraw(type) {
+      // 取消镂空绘制模式
+      this.isDrawingHole = false;
+
+      // 如果已经是当前激活的工具,则取消激活
+      if (this.currentTool === type) {
+        this.deactivateDraw();
+        return;
+      }
+
+      // 先取消之前的绘制模式
+      this.deactivateDraw();
+
+      // 设置当前工具
+      this.currentTool = type;
+      this.drawingMode = type;
+
+      // 重置当前绘制状态
+      this.resetDrawingState();
+
+      switch (type) {
+        case "point":
+          this.drawPoint();
+          break;
+        case "polyline":
+          this.drawPolyline();
+          break;
+        case "polygon":
+          this.drawPolygon();
+          break;
+      }
+    },
+
+    // 重置绘制状态
+    resetDrawingState() {
+      this.currentPositions = [];
+      this.currentEntity = null;
+      // 移除临时预览实体
+      if (this.tempEntity) {
+        viewer.entities.remove(this.tempEntity);
+        this.tempEntity = null;
+      }
+    },
+
+    // 取消绘制模式
+    deactivateDraw() {
+      if (this.handler) {
+        // 移除所有事件监听器
+        this.handler.removeInputAction(SkyScenery.ScreenSpaceEventType.LEFT_CLICK);
+        this.handler.removeInputAction(SkyScenery.ScreenSpaceEventType.MOUSE_MOVE);
+        this.handler.removeInputAction(SkyScenery.ScreenSpaceEventType.RIGHT_CLICK);
+      }
+
+      // 重置状态
+      this.resetDrawingState();
+      this.currentTool = null;
+      this.drawingMode = null;
+      this.isDrawingHole = false;
+    },
+
+    // 绘制点
+    drawPoint() {
+      const that = this;
+      this.handler.setInputAction(function (event) {
+        const ray = viewer.camera.getPickRay(event.position);
+        const position = viewer.scene.globe.pick(ray, viewer.scene);
+
+        if (position) {
+          const cartographic = SkyScenery.Cartographic.fromCartesian(position);
+          const longitude = SkyScenery.Math.toDegrees(cartographic.longitude);
+          const latitude = SkyScenery.Math.toDegrees(cartographic.latitude);
+
+          // 创建点实体(实时渲染)
+          const entity = viewer.entities.add({
+            position: position,
+            point: {
+              show: true,
+              color: SkyScenery.Color.RED,
+              pixelSize: 10,
+              outlineColor: SkyScenery.Color.WHITE,
+              outlineWidth: 2,
+            },
+          });
+
+          that.drawnEntities.push(entity);
+
+          // 转换为geometry格式并保存
+          const geometry = {
+            type: "Point",
+            coordinates: [longitude, latitude],
+          };
+          that.geometries.push(geometry);
+
+          console.log("绘制了点:", geometry);
+
+          // 检查是否绘制了两个元素
+          that.checkAndSendGeometries();
+        }
+      }, SkyScenery.ScreenSpaceEventType.LEFT_CLICK);
+    },
+
+    // 绘制线
+    drawPolyline() {
+      const that = this;
+
+      // 鼠标移动时更新临时线(实时渲染预览)
+      this.handler.setInputAction(function (event) {
+        if (that.currentPositions.length > 0) {
+          const ray = viewer.camera.getPickRay(event.endPosition);
+          const endPosition = viewer.scene.globe.pick(ray, viewer.scene);
+
+          if (endPosition) {
+            const tempPositions = [...that.currentPositions, endPosition];
+
+            // 更新临时预览实体
+            if (!that.tempEntity) {
+              that.tempEntity = viewer.entities.add({
+                polyline: {
+                  show: true,
+                  positions: tempPositions,
+                  material: SkyScenery.Color.BLUE.withAlpha(0.5),
+                  width: 3,
+                },
+              });
+            } else {
+              that.tempEntity.polyline.positions = tempPositions;
+            }
+          }
+        }
+      }, SkyScenery.ScreenSpaceEventType.MOUSE_MOVE);
+
+      // 左键点击添加点
+      this.handler.setInputAction(function (event) {
+        const ray = viewer.camera.getPickRay(event.position);
+        const position = viewer.scene.globe.pick(ray, viewer.scene);
+
+        if (position) {
+          that.currentPositions.push(position.clone());
+
+          // 如果是第一个点,不需要更新实体
+          if (that.currentPositions.length > 1) {
+            // 如果已有实体,更新它
+            if (that.currentEntity) {
+              viewer.entities.remove(that.currentEntity);
+            }
+
+            // 创建当前实体(实时渲染)
+            that.currentEntity = viewer.entities.add({
+              polyline: {
+                show: true,
+                positions: [...that.currentPositions],
+                material: SkyScenery.Color.BLUE,
+                width: 3,
+              },
+            });
+          }
+        }
+      }, SkyScenery.ScreenSpaceEventType.LEFT_CLICK);
+
+      // 右键点击完成绘制
+      this.handler.setInputAction(function () {
+        if (that.currentPositions.length > 1) {
+          // 移除临时预览实体
+          if (that.tempEntity) {
+            viewer.entities.remove(that.tempEntity);
+            that.tempEntity = null;
+          }
+
+          // 否则创建线
+          // 确保当前实体存在
+          if (!that.currentEntity) {
+            that.currentEntity = viewer.entities.add({
+              polyline: {
+                show: true,
+                positions: [...that.currentPositions],
+                material: SkyScenery.Color.BLUE,
+                width: 3,
+              },
+            });
+          }
+
+          that.drawnEntities.push(that.currentEntity);
+
+          // 转换为geometry格式并保存
+          const coordinates = [];
+          that.currentPositions.forEach((pos) => {
+            const cartographic = SkyScenery.Cartographic.fromCartesian(pos);
+            coordinates.push([
+              SkyScenery.Math.toDegrees(cartographic.longitude),
+              SkyScenery.Math.toDegrees(cartographic.latitude),
+            ]);
+          });
+
+          const geometry = {
+            type: "LineString",
+            coordinates: coordinates,
+          };
+          that.geometries.push(geometry);
+
+          console.log("绘制了线:", geometry);
+
+          // 检查是否绘制了两个元素
+          that.checkAndSendGeometries();
+
+          // 取消当前绘制模式
+          that.deactivateDraw();
+        }
+      }, SkyScenery.ScreenSpaceEventType.RIGHT_CLICK);
+    },
+
+    // 绘制面
+    drawPolygon() {
+      const that = this;
+
+      // 鼠标移动时更新临时面(实时渲染预览)
+      this.handler.setInputAction(function (event) {
+        if (that.currentPositions.length > 0) {
+          const ray = viewer.camera.getPickRay(event.endPosition);
+          const endPosition = viewer.scene.globe.pick(ray, viewer.scene);
+
+          if (endPosition) {
+            // 为了预览效果,临时闭合多边形
+            const tempPositions = [
+              ...that.currentPositions,
+              endPosition,
+              that.currentPositions[0],
+            ];
+
+            // 更新临时预览实体
+            if (!that.tempEntity) {
+              that.tempEntity = viewer.entities.add({
+                polygon: {
+                  show: true,
+                  hierarchy: new SkyScenery.PolygonHierarchy(tempPositions),
+                  material: new SkyScenery.ColorMaterialProperty(
+                    new SkyScenery.Color(0, 0, 1, 0.2)
+                  ),
+                  outline: true,
+                  outlineColor: SkyScenery.Color.BLUE.withAlpha(0.5),
+                  outlineWidth: 2,
+                },
+              });
+            } else {
+              that.tempEntity.polygon.hierarchy = new SkyScenery.PolygonHierarchy(
+                tempPositions
+              );
+            }
+          }
+        }
+      }, SkyScenery.ScreenSpaceEventType.MOUSE_MOVE);
+
+      // 左键点击添加点
+      this.handler.setInputAction(function (event) {
+        const ray = viewer.camera.getPickRay(event.position);
+        const position = viewer.scene.globe.pick(ray, viewer.scene);
+
+        if (position) {
+          // 检查是否点击了第一个点附近(自动闭合)
+          if (
+            that.currentPositions.length > 2 &&
+            that.isPositionNearFirst(position, that.currentPositions[0])
+          ) {
+            // 完成多边形绘制
+            that.finalizePolygonDrawing();
+            that.deactivateDraw();
+            return;
+          }
+
+          that.currentPositions.push(position.clone());
+
+          // 如果有足够的点,更新多边形实体(实时渲染)
+          if (that.currentPositions.length > 2) {
+            // 闭合多边形
+            const closedPositions = [...that.currentPositions, that.currentPositions[0]];
+            // 如果已有实体,更新它
+            if (that.currentEntity) {
+              viewer.entities.remove(that.currentEntity);
+            }
+
+            // 创建当前实体
+            that.currentEntity = viewer.entities.add({
+              polygon: {
+                show: true,
+                hierarchy: new SkyScenery.PolygonHierarchy(closedPositions),
+                material: new SkyScenery.ColorMaterialProperty(
+                  new SkyScenery.Color(0, 0, 1, 0.3)
+                ),
+                outline: true,
+                outlineColor: SkyScenery.Color.BLUE,
+                outlineWidth: 2,
+              },
+            });
+          }
+        }
+      }, SkyScenery.ScreenSpaceEventType.LEFT_CLICK);
+
+      // 右键点击完成绘制
+      this.handler.setInputAction(function () {
+        if (that.currentPositions.length > 2) {
+          that.finalizePolygonDrawing();
+
+          // 检查是否绘制了两个元素
+          that.checkAndSendGeometries();
+
+          // 取消当前绘制模式
+          that.deactivateDraw();
+        }
+      }, SkyScenery.ScreenSpaceEventType.RIGHT_CLICK);
+    },
+
+    // 完成多边形绘制
+    finalizePolygonDrawing() {
+      // 移除临时预览实体
+      if (this.tempEntity) {
+        viewer.entities.remove(this.tempEntity);
+        this.tempEntity = null;
+      }
+
+      // 确保多边形是闭合的
+      let closedPositions = [...this.currentPositions];
+      // 创建最终的多边形实体
+      if (this.currentEntity) {
+        viewer.entities.remove(this.currentEntity);
+      }
+
+      this.currentEntity = viewer.entities.add({
+        polygon: {
+          show: true,
+          hierarchy: new SkyScenery.PolygonHierarchy(closedPositions),
+          material: new SkyScenery.ColorMaterialProperty(
+            new SkyScenery.Color(0, 0, 1, 0.3)
+          ),
+          outline: true,
+          outlineColor: SkyScenery.Color.BLUE,
+          outlineWidth: 2,
+        },
+      });
 
-        };
+      this.drawnEntities.push(this.currentEntity);
+
+      // 转换为geometry格式并保存(不包含重复的最后一个点)
+      const coordinates = [];
+      const mainRing = [];
+      for (let i = 0; i < closedPositions.length; i++) {
+        const cartographic = SkyScenery.Cartographic.fromCartesian(closedPositions[i]);
+        mainRing.push([
+          SkyScenery.Math.toDegrees(cartographic.longitude),
+          SkyScenery.Math.toDegrees(cartographic.latitude),
+        ]);
+      }
+      const cartographic = SkyScenery.Cartographic.fromCartesian(closedPositions[0]);
+      mainRing.push([
+        SkyScenery.Math.toDegrees(cartographic.longitude),
+        SkyScenery.Math.toDegrees(cartographic.latitude),
+      ]);
+      coordinates.push(mainRing);
+
+      const geometry = {
+        type: "Polygon",
+        coordinates: coordinates, // GeoJSON格式
+        holes: [], // 用于存储镂空区域
+      };
+
+      // 保存实体和几何对象的关联
+      this.currentEntity.geometryRef = geometry;
+      this.geometries.push(geometry);
+
+      console.log("绘制了面:", geometry);
     },
-    mounted() {
+
+    // 开始绘制镂空
+    startHoleDrawing() {
+      // 如果已经在绘制镂空,则取消
+      if (this.isDrawingHole) {
+        this.isDrawingHole = false;
+        this.deactivateDraw();
+        return;
+      }
+
+      // 取消其他绘制模式
+      this.deactivateDraw();
+
+      // 设置为镂空绘制模式
+      this.isDrawingHole = true;
+
+      console.log("请点击一个多边形以添加镂空");
+
+      // 设置点击事件选择多边形
+      const that = this;
+      this.handler.setInputAction(function (event) {
+        // 拾取实体
+        const pickedObject = viewer.scene.pick(event.position);
+        if (pickedObject && pickedObject.id && pickedObject.id.polygon) {
+          const polygonEntity = pickedObject.id;
+
+          // 检查是否有对应的几何对象
+          if (polygonEntity.geometryRef && polygonEntity.geometryRef.type === "Polygon") {
+            that.currentPolygonEntity = polygonEntity;
+            that.currentPolygonGeometry = polygonEntity.geometryRef;
+
+            console.log("已选择多边形,现在绘制镂空区域");
+
+            // 开始绘制镂空区域(使用多边形绘制逻辑,但最后添加为镂空)
+            that.resetDrawingState();
+            that.drawHole();
+          } else {
+            console.log("选择的不是有效的多边形");
+          }
+        } else {
+          console.log("未选中任何多边形");
+        }
+      }, SkyScenery.ScreenSpaceEventType.LEFT_CLICK);
     },
-    methods: {
+
+    // 绘制镂空区域
+    drawHole() {
+      const that = this;
+
+      // 清除之前的事件
+      this.handler.removeInputAction(SkyScenery.ScreenSpaceEventType.LEFT_CLICK);
+
+      // 鼠标移动时更新临时镂空区域
+      this.handler.setInputAction(function (event) {
+        if (that.currentPositions.length > 0) {
+          const ray = viewer.camera.getPickRay(event.endPosition);
+          const endPosition = viewer.scene.globe.pick(ray, viewer.scene);
+
+          if (endPosition) {
+            // 为了预览效果,临时闭合多边形
+            const tempPositions = [
+              ...that.currentPositions,
+              endPosition,
+              that.currentPositions[0],
+            ];
+
+            // 更新临时预览实体
+            if (!that.tempEntity) {
+              that.tempEntity = viewer.entities.add({
+                polygon: {
+                  show: true,
+                  hierarchy: new SkyScenery.PolygonHierarchy(tempPositions),
+                  material: new SkyScenery.ColorMaterialProperty(
+                    new SkyScenery.Color(1, 0, 0, 0.3)
+                  ),
+                  outline: true,
+                  outlineColor: SkyScenery.Color.RED,
+                  outlineWidth: 2,
+                },
+              });
+            } else {
+              that.tempEntity.polygon.hierarchy = new SkyScenery.PolygonHierarchy(
+                tempPositions
+              );
+            }
+          }
+        }
+      }, SkyScenery.ScreenSpaceEventType.MOUSE_MOVE);
+
+      // 左键点击添加点
+      this.handler.setInputAction(function (event) {
+        const ray = viewer.camera.getPickRay(event.position);
+        const position = viewer.scene.globe.pick(ray, viewer.scene);
+
+        if (position) {
+          // 检查是否点击了第一个点附近(自动闭合)
+          if (
+            that.currentPositions.length > 2 &&
+            that.isPositionNearFirst(position, that.currentPositions[0])
+          ) {
+            // 完成镂空绘制
+            that.finalizeHoleDrawing();
+            return;
+          }
+
+          that.currentPositions.push(position.clone());
+        }
+      }, SkyScenery.ScreenSpaceEventType.LEFT_CLICK);
+
+      // 右键点击完成绘制
+      this.handler.setInputAction(function () {
+        if (that.currentPositions.length > 2) {
+          that.finalizeHoleDrawing();
+        }
+      }, SkyScenery.ScreenSpaceEventType.RIGHT_CLICK);
+    },
+
+    // 完成镂空绘制
+    finalizeHoleDrawing() {
+      // 移除临时预览实体
+      if (this.tempEntity) {
+        viewer.entities.remove(this.tempEntity);
+        this.tempEntity = null;
+      }
+
+      // 确保镂空区域是闭合的
+      let closedPositions = [...this.currentPositions];
+
+      // 转换为几何坐标
+      const holeCoordinates = [];
+      for (let i = 0; i < closedPositions.length; i++) {
+        const cartographic = SkyScenery.Cartographic.fromCartesian(closedPositions[i]);
+        holeCoordinates.push([
+          SkyScenery.Math.toDegrees(cartographic.longitude),
+          SkyScenery.Math.toDegrees(cartographic.latitude),
+        ]);
+      }
+
+      const cartographic = SkyScenery.Cartographic.fromCartesian(closedPositions[0]);
+      holeCoordinates.push([
+        SkyScenery.Math.toDegrees(cartographic.longitude),
+        SkyScenery.Math.toDegrees(cartographic.latitude),
+      ]);
+      // 添加到几何对象的镂空数组
+      if (!this.currentPolygonGeometry.holes) {
+        this.currentPolygonGeometry.holes = [];
+      }
+      this.currentPolygonGeometry.holes.push(holeCoordinates);
+
+      // 更新多边形的层级结构以包含镂空
+      const polygonHierarchy = this.buildPolygonHierarchyWithHoles(
+        this.currentPolygonGeometry.coordinates[0],
+        this.currentPolygonGeometry.holes
+      );
+
+      // 更新实体显示
+      this.currentPolygonEntity.polygon.hierarchy = polygonHierarchy;
+
+      console.log("添加了镂空区域:", holeCoordinates);
+      console.log("更新后的多边形几何:", this.currentPolygonGeometry);
+
+      // 重置状态
+      this.resetDrawingState();
+      this.isDrawingHole = false;
+      this.currentPolygonEntity = null;
+      this.currentPolygonGeometry = null;
+
+      // 取消绘制模式
+      this.deactivateDraw();
+    },
+
+    // 构建包含镂空的多边形层级结构
+    buildPolygonHierarchyWithHoles(outerRing, holes) {
+      // 将外部环转换为Cartesian3数组
+      const outerRingPositions = [];
+      outerRing.forEach((coord) => {
+        const cartesian = SkyScenery.Cartesian3.fromDegrees(coord[0], coord[1]);
+        outerRingPositions.push(cartesian);
+      });
+      // 闭合外部环
+      outerRingPositions.push(outerRingPositions[0]);
+
+      // 创建层级结构
+      const hierarchy = new SkyScenery.PolygonHierarchy(outerRingPositions);
+
+      // 添加镂空
+      if (holes && holes.length > 0) {
+        hierarchy.holes = holes.map((hole) => {
+          const holePositions = [];
+          hole.forEach((coord) => {
+            const cartesian = SkyScenery.Cartesian3.fromDegrees(coord[0], coord[1]);
+            holePositions.push(cartesian);
+          });
+          // 闭合镂空环
+          holePositions.push(holePositions[0]);
+          return new SkyScenery.PolygonHierarchy(holePositions);
+        });
+      }
+
+      return hierarchy;
+    },
+
+    // 检查点是否靠近第一个点
+    isPositionNearFirst(position, firstPosition, tolerance = 10) {
+      // 单位:米
+      const distance = SkyScenery.Cartesian3.distance(position, firstPosition);
+      return distance < tolerance;
+    },
+
+    // 检查是否绘制了两个元素,如果是则调用后台接口
+    checkAndSendGeometries() {
+      if (this.geometries.length >= 2) {
+        console.log("已绘制两个或更多几何元素,准备发送到后台");
+        this.sendGeometriesToBackend();
+      }
+    },
+
+    // 发送几何数据到后台接口
+    sendGeometriesToBackend() {
+      // 这里使用axios发送请求,需要确保项目中已安装并导入axios
+      const geometriesToSend = this.geometries.slice(0, 2); // 只取前两个几何元素
+      let FeatureCollectionFeatures = [];
+      geometriesToSend.forEach((item) => {
+        FeatureCollectionFeatures.push({
+          type: "Feature",
+          properties: {},
+          geometry: {
+            type: item.type,
+            coordinates: item.coordinates,
+          },
+        });
+      });
+      // 构造请求数据
+      const requestData = {
+        type: "FeatureCollection",
+        features: FeatureCollectionFeatures,
+        timestamp: new Date().getTime(),
+      };
+
+      console.log("发送到后台的数据:", requestData);
+
+      // 示例:使用axios发送POST请求
+      // 这里需要替换为实际的后台接口URL
+      const apiUrl = "/api/geometry/submit"; // 假设的接口地址
+
+      // 实际项目中使用以下代码发送请求
+      skszk
+        .topology(requestData)
+        .then((res) => {
+          this.$message({
+            message: res.message,
+            type: "success",
+          });
+        })
+        .catch((error) => {
+          console.error("后台接口调用失败:", error);
+        });
+      // 由于是示例,这里只打印日志
+      console.log(
+        `假设已调用后台接口 ${apiUrl},发送了 ${geometriesToSend.length} 个几何元素`
+      );
+    },
+
+    // 清除所有绘制的元素
+    clearAll() {
+      // 移除所有实体
+      this.drawnEntities.forEach((entity) => {
+        viewer.entities.remove(entity);
+      });
+
+      // 清空数组
+      this.drawnEntities = [];
+      this.geometries = [];
+
+      // 取消当前绘制模式
+      this.deactivateDraw();
+
+      console.log("已清除所有绘制的元素");
+    },
+  },
+  beforeUnmount() {
+    // 组件卸载前清理资源
+    this.deactivateDraw();
+    if (this.handler) {
+      this.handler.destroy();
     }
+  },
 };
 </script>
 
 <style lang="less" scoped>
-.container {
-    width: 1920px;
-    margin: 0 auto;
+.example {
+  width: 100%;
+  height: 100vh;
+  position: relative;
+  overflow: hidden;
+}
+
+.toolbar {
+  position: absolute;
+  top: 20px;
+  left: 20px;
+  z-index: 1000;
+  background: rgba(255, 255, 255, 0.9);
+  border-radius: 8px;
+  padding: 10px;
+  box-shadow: 0 2px 10px rgba(0, 0, 0, 0.2);
+  display: flex;
+  flex-direction: column;
+  gap: 8px;
+}
+
+.tool-item {
+  padding: 10px 20px;
+  cursor: pointer;
+  border-radius: 4px;
+  transition: all 0.3s ease;
+  user-select: none;
+  font-size: 14px;
+}
+
+.tool-item:hover {
+  background: #f0f0f0;
+}
+
+.tool-item.active {
+  background: #409eff;
+  color: white;
+}
+
+#skysceneryContainer {
+  width: 100%;
+  height: 100%;
 }
-</style>
+</style>

+ 7 - 0
vue.config.js

@@ -95,6 +95,13 @@ module.exports = defineConfig({
           '^/proxy_dms': ''
         }
       },
+      '/oneMap/': {
+        target: 'http://127.0.0.1:10308/oneMap',
+        changeOrigin: true,
+        pathRewrite: {
+          '^/oneMap': ''
+        }
+      },
     },
   }
 })