|
@@ -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()
|