浏览代码

绘制修改

zhiyuan-007 2 月之前
父节点
当前提交
9f6a4f41f7
共有 1 个文件被更改,包括 179 次插入14 次删除
  1. 179 14
      src/units/map/addDrawEvent.js

+ 179 - 14
src/units/map/addDrawEvent.js

@@ -1,6 +1,8 @@
 import GraphicsLayer from "@arcgis/core/layers/GraphicsLayer.js";
 import SketchViewModel from "@arcgis/core/widgets/Sketch/SketchViewModel.js";
 import Graphic from "@arcgis/core/Graphic.js";
+import Mesh from "@arcgis/core/geometry/Mesh.js";
+import Point from "@arcgis/core/geometry/Point.js";
 
 class AddDrawEvent {
     constructor(options) {
@@ -35,21 +37,184 @@ class AddDrawEvent {
             }
         });
     }
+
+    createTruncatedConeWithCylinder(bottomRadius, topRadius, coneHeight, cylinderHeight) {
+        const segments = 30; // 分割数,越大越平滑
+        let vertices = [];
+        let faces = [];
+        let position = new Point({
+            x: 0,
+            y: 0,
+            z: 0
+        })
+        // 生成圆台下圆(同时作为圆柱体的上圆),位于 z = position.z
+        for (let i = 0; i < segments; i++) {
+            let angle = (i / segments) * 2 * Math.PI;
+            vertices.push(
+                position.x + Math.cos(angle) * bottomRadius,
+                position.y + Math.sin(angle) * bottomRadius,
+                position.z
+            );
+        }
+
+        // 生成圆台上圆,位于 z = position.z + coneHeight
+        for (let i = 0; i < segments; i++) {
+            let angle = (i / segments) * 2 * Math.PI;
+            vertices.push(
+                position.x + Math.cos(angle) * topRadius,
+                position.y + Math.sin(angle) * topRadius,
+                position.z + coneHeight
+            );
+        }
+
+        // 生成圆柱体下圆,位于 z = position.z - cylinderHeight
+        for (let i = 0; i < segments; i++) {
+            let angle = (i / segments) * 2 * Math.PI;
+            vertices.push(
+                position.x + Math.cos(angle) * bottomRadius,
+                position.y + Math.sin(angle) * bottomRadius,
+                position.z - cylinderHeight
+            );
+        }
+
+        // 构造圆台侧面(连接圆台下圆与上圆)
+        for (let i = 0; i < segments; i++) {
+            let next = (i + 1) % segments;
+            let bottom_i = i;             // 圆台下圆
+            let bottom_next = next;
+            let top_i = i + segments;     // 圆台上圆
+            let top_next = next + segments;
+            faces.push(bottom_i, bottom_next, top_i);
+            faces.push(bottom_next, top_next, top_i);
+        }
+
+        // 构造圆台顶面
+        for (let i = 1; i < segments - 1; i++) {
+            faces.push(segments, segments + i, segments + i + 1);
+        }
+
+        // 构造圆柱体侧面(连接圆台下圆和圆柱体下圆)
+        for (let i = 0; i < segments; i++) {
+            let next = (i + 1) % segments;
+            let top_i = i;              // 圆柱体上圆(与圆台下圆相同)
+            let top_next = next;
+            let bottom_i = i + 2 * segments; // 圆柱体下圆
+            let bottom_next = next + 2 * segments;
+            faces.push(top_i, top_next, bottom_i);
+            faces.push(top_next, bottom_next, bottom_i);
+        }
+
+        // 构造圆柱体底面
+        for (let i = 1; i < segments - 1; i++) {
+            faces.push(2 * segments, 2 * segments + i, 2 * segments + i + 1);
+        }
+
+        return new Mesh({
+            vertexAttributes: {
+                position: vertices
+            },
+            components: [
+                {
+                    faces: faces,
+                    material: { color: this.symbol.color },
+                }
+            ],
+            spatialReference: {
+                wkid: 102100 // 空间参考系
+            }
+        });
+    }
+
+
+
+
+
+    createTruncatedCone(bottomRadius, topRadius, height) {
+        let position = new Point({
+            x: 0,
+            y: 0,
+            z: 0
+        })
+        const segments = 30; // 细分程度,值越大越平滑
+        let vertices = [];
+        let faces = [];
+
+        // 下圆
+        for (let i = 0; i < segments; i++) {
+            let angle = (i / segments) * 2 * Math.PI;
+            // 将圆心坐标 (cx, cy, cz) 加到每个顶点的位置
+            vertices.push(position.x + Math.cos(angle) * bottomRadius, position.y + Math.sin(angle) * bottomRadius, position.z);
+        }
+
+        // 上圆
+        for (let i = 0; i < segments; i++) {
+            let angle = (i / segments) * 2 * Math.PI;
+            // 将圆心坐标 (cx, cy, cz) 加到每个顶点的位置
+            vertices.push(position.x + Math.cos(angle) * topRadius, position.y + Math.sin(angle) * topRadius, position.z + height);
+        }
+
+        // 侧面
+        for (let i = 0; i < segments; i++) {
+            let next = (i + 1) % segments;
+            let bottom1 = i;
+            let bottom2 = next;
+            let top1 = i + segments;
+            let top2 = next + segments;
+
+            faces.push(bottom1, bottom2, top1);
+            faces.push(bottom2, top2, top1);
+        }
+
+        // 底面
+        for (let i = 1; i < segments - 1; i++) {
+            faces.push(0, i, i + 1);
+        }
+
+        // 顶面
+        for (let i = 1; i < segments - 1; i++) {
+            faces.push(segments, segments + i, segments + i + 1);
+        }
+
+        return new Mesh({
+            vertexAttributes: {
+                position: vertices
+            },
+            components: [{
+                faces: faces,
+                material: { color: this.symbol.color }
+            }],
+            spatialReference: {
+                wkid: 102100 // 空间参考系
+            }
+        });
+    }
     start(symbol,type){
-        if(symbol){
-            switch (type){
-                case "point":
-                    this.sketchViewModel.pointSymbol = symbol;
-                    break;
-                case "polyline":
-                    this.sketchViewModel.polylineSymbol = symbol;
-                    break;
-                default :
-                    this.sketchViewModel.polygonSymbol = symbol;
-                    break;
+        switch (type){
+            case "mesh":
+                let mesh = this.createTruncatedCone(this.symbol.bottomRadius, this.symbol.topRadius, this.symbol.height);
+                this.sketchViewModel.place(mesh)
+           break;
+            case "funnel":
+                let funnel = this.createTruncatedConeWithCylinder(this.symbol.bottomRadius, this.symbol.topRadius, this.symbol.coneHeight, this.symbol.cylinderHeight);
+                this.sketchViewModel.place(funnel)
+            break;
+        default:
+            if(symbol){
+                switch (type){
+                    case "point":
+                        this.sketchViewModel.pointSymbol = symbol;
+                        break;
+                    case "polyline":
+                        this.sketchViewModel.polylineSymbol = symbol;
+                        break;
+                    default :
+                        this.sketchViewModel.polygonSymbol = symbol;
+                        break;
+                }
             }
+            this.sketchViewModel.create(type);
+           break;
         }
-        this.sketchViewModel.create(type);
     }
     update(){
         if(this.path){
@@ -64,8 +229,8 @@ class AddDrawEvent {
             });
             this.graphicLayer.add(this.graphic);
         }
-        // const updateOptions = { tool: "reshape", highlightOptions: { enabled: false }};
-        // this.sketchViewModel.update([this.graphic],updateOptions);
+        const updateOptions = { tool: "reshape", highlightOptions: { enabled: false }};
+        this.sketchViewModel.update([this.graphic],updateOptions);
     }
     createListenerEvent(callback){
         this.clearCreateListenerEvent()