Procházet zdrojové kódy

进行绘制工具的分离,增加绘制内容

不会爬树的猴 před 2 roky
rodič
revize
482cceb850

+ 5 - 0
src/assets/fonts/fonts.css

@@ -152,4 +152,9 @@
 /* 绘制墙图标 */
 .app-icon-draw-text::before {
 	content: '\e732';
+}
+
+/* 绘制房屋图标 */
+.app-icon-draw-house::before {
+	content: '\e700';
 }

binární
src/assets/fonts/iconfont.ttf


+ 22 - 58
src/components/CrMap/CircleMaterialProperty.js

@@ -12,12 +12,9 @@ class CircleMaterialProperty {
 	/**
 	 * @param {JSON} options 配置项
 	 * @param {Cesium.Viewer} options.viewer 着色器运行所需的视图
-	 * @param {Cesium.Color} options.color [的颜色,默认蓝色] 可选
+	 * @param {Cesium.Color} options.color [圆环的颜色,默认蓝色] 可选
 	 * @param {Number} options.duration [循环时间 默认1000] 可选
-	 * @param {JSON} options.param 着色器参数
-	 * @param {Number} options.param.count [数量 可选 默认为1]
-	 * @param {String} options.param.direction [方向 可选 默认竖直 ] 取值vertical/horizontal
-	 * @param {String} options.param.order [顺序 可选 上下/下上/顺时针/逆时针 与方向配合使用 ] 取值+/-
+	 * @param {Number} options.count [圆环的数量 可选 默认为1]
 	 */
 	constructor(options) {
 		/* 着色器运行依赖的视图 */
@@ -25,8 +22,10 @@ class CircleMaterialProperty {
 		/* 变更事件 */
 		this._definitionChanged = new Cesium.Event();
 		this._color = undefined;
-		/* 的颜色 */
+		/* 扩算圆环的颜色 */
 		this.color = options.color || Cesium.Color.BLUE;
+		/* 扩散圆环的数量 */
+		this.count = options.count || 1.0;
 		/* 动态循环周期 */
 		this.duration = options.duration || 1000;
 		/* 默认时间 */
@@ -37,9 +36,7 @@ class CircleMaterialProperty {
 		this._param = {
 			color: this.color._value.toCssColorString(),
 			duration: this.duration,
-			count: 0,
-			direction: '',
-			order: '',
+			count: this.count,
 		}
 		/* 将材质加入缓存 以便重复利用 */
 		Cesium.Material._materialCache.addMaterial(this._materialTypeName, {
@@ -48,6 +45,7 @@ class CircleMaterialProperty {
 				uniforms: {
 					time: 0,
 					color: new Cesium.Color(1.0, 0.0, 0.0, 0.5),
+					count: 1.0,
 				},
 				source: this._getCircleMaterial(),
 			},
@@ -123,50 +121,6 @@ class CircleMaterialProperty {
 		// 	"}";
 
 		//真正意义上的圆环扩散
-		// let circleMaterial = "czm_material czm_getMaterial(czm_materialInput materialInput)\n" +
-		// 	"{\n" +
-		// 	"  czm_material material = czm_getDefaultMaterial(materialInput);\n" +
-		// 	"  material.diffuse = 1.5 * color.rgb;\n" +
-		// 	"  vec2 st = materialInput.st;\n" +
-		// 	"  vec3 str = materialInput.str;\n" +
-		// 	"  float dis = distance(st, vec2(0.5, 0.5));\n" +
-		// 	"  float per = fract(time);\n" +
-		// 	"  if (abs(str.z) > 0.001)\n" +
-		// 	"  {\n" +
-		// 	"     //着色器渲染停止,不在绘制内容  \n" +
-		// 	"     discard;\n" +
-		// 	"  }\n" +
-		// 	"  if (dis > 0.5)\n" +
-		// 	"  {\n" +
-		// 	"     //超出半径范围时,着色器渲染停止  \n" +
-		// 	"     discard;\n" +
-		// 	"  } else {\n" +
-		// 	"     //把半径分成count份,每两份之间的间隔距离  \n" +
-		// 	"     float perDis = 0.5 / 3.0;\n" +
-		// 	"     float disNum;\n" +
-		// 	"     float bl = 0.0;\n" +
-		// 	"     //循环,最多999个环  \n" +
-		// 	"     for (int i = 0; i <= 999; i++)\n" +
-		// 	"     {\n" +
-		// 	"        //判断是否属于数量内的环  \n" +
-		// 	"        if (float(i) <= 3.0)\n" +
-		// 	"        {\n" +
-		// 	"           disNum = perDis * float(i) - dis + per / 3.0;\n" +
-		// 	"           if (disNum > 0.0)\n" +
-		// 	"           {\n" +
-		// 	"               if (disNum < perDis)\n" +
-		// 	"               {\n" +
-		// 	"                  bl = 1.0 - disNum / perDis;\n" +
-		// 	"               } else if (disNum - perDis < perDis) {\n" +
-		// 	"                  bl = 1.0 - abs(1.0 - disNum / perDis);\n" +
-		// 	"               }\n" +
-		// 	"               material.alpha = pow(bl, 0.3);\n" +
-		// 	"           }\n" +
-		// 	"        }\n" +
-		// 	"     }\n" +
-		// 	"  }\n" +
-		// 	"  return material;\n" +
-		// 	"}\n";
 		let circleMaterial = "czm_material czm_getMaterial(czm_materialInput materialInput)\n" +
 			"{\n" +
 			"  czm_material material = czm_getDefaultMaterial(materialInput);\n" +
@@ -186,17 +140,26 @@ class CircleMaterialProperty {
 			"     discard;\n" +
 			"  } else {\n" +
 			"     //把半径分成count份,每两份之间的间隔距离  \n" +
-			"     float perDis = 0.5 / 3.0;\n" +
+			"     float perDis = 0.5 / count;\n" +
 			"     float disNum;\n" +
 			"     float bl = 0.0;\n" +
 			"     //循环,最多999个环  \n" +
-			"     for (int i = 0; i <= 3; i++)\n" +
+			"     for (int i = 0; i <= 999; i++)\n" +
 			"     {\n" +
 			"        //判断是否属于数量内的环  \n" +
-			"        disNum = (0.5 - float(i)*perDis)/0.9*per; \n" +
-			"        if(dis > disNum && dis < disNum + 0.03)\n" +
+			"        if (float(i) <= count)\n" +
 			"        {\n" +
-			"            material.alpha = 0.0;\n" +
+			"           disNum = perDis * float(i) - dis + per / count;\n" +
+			"           if (disNum > 0.0)\n" +
+			"           {\n" +
+			"               if (disNum < perDis)\n" +
+			"               {\n" +
+			"                  bl = 1.0 - disNum / perDis;\n" +
+			"               } else if (disNum - perDis < perDis) {\n" +
+			"                  bl = 1.0 - abs(1.0 - disNum / perDis);\n" +
+			"               }\n" +
+			"               material.alpha = color.a * pow(bl, 3.0);\n" +
+			"           }\n" +
 			"        }\n" +
 			"     }\n" +
 			"  }\n" +
@@ -229,6 +192,7 @@ Object.assign(CircleMaterialProperty.prototype, {
 		}
 		result.color = Cesium.Property.getValueOrClonedDefault(this._color, time, Cesium.Color.BLUE, result
 			.color);
+		result.count = this.count;
 		if (this.duration) {
 			result.time = (((new Date()).getTime() - this._time) % this.duration) / this.duration;
 		}

+ 37 - 20
src/components/CrMap/CrMap.vue

@@ -5,11 +5,14 @@
 import { param } from 'jquery';
 import { defineExpose, onMounted, getCurrentInstance } from 'vue';
 /* 注册方法 */
-const emit = defineEmits(['onEditWall']);
+const emit = defineEmits(['onEditProperty']);
 
 import { CrMap } from './CrMap.js';
 import CommonTools from './CommonTools.js';
 import { SketchViewModel } from './SketchViewModel.js';
+
+import { DrawTools } from './DrawTools.js';
+
 import { point } from '@turf/turf';
 const { proxy } = getCurrentInstance();
 /* 组件对外提供的方法 */
@@ -151,14 +154,14 @@ defineExpose({
 	 * 清除绘制内容
 	 */
 	onClearDraw: function() {
-		proxy.sketchViewModel.sketchClear();
+		proxy.drawTools.Clear();
 	},
 
 	/**
 	 * 鼠标点击绘制可编辑贴地线
 	 */
 	onMouseDrawEditLine: function() {
-		proxy.sketchViewModel.sketchTools(SketchViewModel.SketchType.Line, {
+		proxy.drawTools.draw(DrawTools.DrawType.Polyline, {
 			isEdit: true
 		});
 	},
@@ -167,7 +170,7 @@ defineExpose({
 	 * 鼠标点击绘制可编辑贴地面
 	 */
 	onMouseDrawEditPolygon: function() {
-		proxy.sketchViewModel.sketchTools(SketchViewModel.SketchType.Polygon, {
+		proxy.drawTools.draw(DrawTools.DrawType.Polygon, {
 			isEdit: true
 		});
 	},
@@ -176,7 +179,7 @@ defineExpose({
 	 * 鼠标点击绘制可编辑矩形
 	 */
 	onMouseDrawEditRectangle: function() {
-		proxy.sketchViewModel.sketchTools(SketchViewModel.SketchType.Rectangle, {
+		proxy.drawTools.draw(DrawTools.DrawType.Rectangle, {
 			isEdit: true
 		});
 	},
@@ -185,7 +188,7 @@ defineExpose({
 	 * 鼠标点击绘制可编辑圆
 	 */
 	onMouseDrawEditCircle: function() {
-		proxy.sketchViewModel.sketchTools(SketchViewModel.SketchType.Circle, {
+		proxy.drawTools.draw(DrawTools.DrawType.Circle, {
 			isEdit: true
 		});
 	},
@@ -194,9 +197,8 @@ defineExpose({
 	 * 鼠标点击绘制可编辑动态墙
 	 */
 	onMouseDrawDynamicEditWall: function() {
-		proxy.sketchViewModel.sketchTools(SketchViewModel.SketchType.Wall, {
-			isEdit: true,
-			wallType: SketchViewModel.SketchWallType.DynamicWall
+		proxy.drawTools.draw(DrawTools.DrawType.DynamicWall, {
+			isEdit: true
 		});
 	},
 
@@ -204,9 +206,8 @@ defineExpose({
 	 * 鼠标点击绘制可编辑颜色墙
 	 */
 	onMouseDrawColorEditWall: function() {
-		proxy.sketchViewModel.sketchTools(SketchViewModel.SketchType.Wall, {
-			isEdit: true,
-			wallType: SketchViewModel.SketchWallType.ColorWall
+		proxy.drawTools.draw(DrawTools.DrawType.NormalWall, {
+			isEdit: true
 		});
 	},
 
@@ -214,9 +215,8 @@ defineExpose({
 	 * 鼠标点击绘制可编辑文字墙
 	 */
 	onMouseDrawEditText: function() {
-		proxy.sketchViewModel.sketchTools(SketchViewModel.SketchType.Wall, {
-			isEdit: true,
-			wallType: SketchViewModel.SketchWallType.Text
+		proxy.drawTools.draw(DrawTools.DrawType.TextWall, {
+			isEdit: true
 		});
 	},
 
@@ -224,7 +224,16 @@ defineExpose({
 	 * 绘制可编辑动态圆
 	 */
 	onMouseDrawDynamicCircle: function() {
-		proxy.sketchViewModel.sketchTools(SketchViewModel.SketchType.DynamicCircle, {
+		proxy.drawTools.draw(DrawTools.DrawType.DynamicCircle, {
+			isEdit: true
+		});
+	},
+
+	/**
+	 * 绘制可编辑体
+	 */
+	onMoouseDrawPolygonBody: function() {
+		proxy.drawTools.draw(DrawTools.DrawType.House, {
 			isEdit: true
 		});
 	},
@@ -233,8 +242,8 @@ defineExpose({
 	 * 更新墙属性
 	 * @param {JSON} params 参数配置项
 	 */
-	onSubmitEditWall: function(params) {
-		proxy.sketchViewModel.updateEditEntityWall(params);
+	onSubmitEditProperty: function(params) {
+		proxy.drawTools.updateEditEntityProperty(params);
 	}
 });
 /* 初始化 */
@@ -257,9 +266,17 @@ onMounted(() => {
 		isRetainDrawPoint: true
 	});
 
+	/* 创建绘制类工具 */
+	proxy.drawTools = new DrawTools(proxy.CMapApi.getViewer(), {
+		iconType: DrawTools.IconType.Blue,
+		isDrawPoint: true,
+		isRetainDrawPoint: true
+	});
+
 	/* 创建监听 */
-	proxy.sketchViewModel.onEditWall = param => {
-		emit('onEditWall', param);
+	proxy.drawTools.onEditProperty = param => {
+		console.log('===调用编辑代理>>>', param);
+		emit('onEditProperty', param);
 	};
 
 	/* 添加暗夜版图层 */

Rozdílová data souboru nebyla zobrazena, protože soubor je příliš velký
+ 118 - 0
src/components/CrMap/DrawTools.js


+ 146 - 0
src/components/CrMap/LightMaterialProperty.js

@@ -0,0 +1,146 @@
+/**
+ * 创建者:王成
+ * 操作系统:MAC
+ * 创建日期:2023年1月4日
+ * 描述:泛光材质
+ */
+
+/* 引入Cesium */
+import * as Cesium from 'cesium';
+
+class LightMaterialProperty {
+	/**
+	 * @param {JSON} options 配置项
+	 * @param {Cesium.Viewer} options.viewer 着色器运行所需的视图
+	 * @param {Cesium.Color} options.color [墙的颜色,默认蓝色] 可选
+	 */
+	constructor(options) {
+		/* 着色器运行依赖的视图 */
+		this._viewer = options.viewer;
+		/* 变更事件 */
+		this._definitionChanged = new Cesium.Event();
+		this._color = undefined;
+		/* 墙的颜色 */
+		this.color = options.color || Cesium.Color.BLUE;
+		this.duration = 5000;
+		/* 默认时间 */
+		this._time = (new Date()).getTime();
+		/* 材质类型名称 */
+		this._materialTypeName = 'jtLightMaterial'
+		/* 存储相关参数的属性 以便后期进行追踪修改 */
+		this._param = {
+			color: this.color._value.toCssColorString(),
+		}
+		/* 将材质加入缓存 以便重复利用 */
+		Cesium.Material._materialCache.addMaterial(this._materialTypeName, {
+			fabric: {
+				type: this._materialTypeName,
+				uniforms: {
+					time: -20,
+					color: new Cesium.Color(1.0, 0.0, 0.0, 0.5),
+					outStr: 0,
+				},
+				source: this._getShaderSource()
+			},
+			translucent: function(material) {
+				/* 材质是否半透明 */
+				return true;
+			}
+		});
+	}
+
+	/**
+	 * 着色器源码
+	 */
+	_getShaderSource() {
+		let materail = '';
+		// materail += 'varying vec3 v_positionEC;\n'
+		materail += 'czm_material czm_getMaterial(czm_materialInput materialInput){\n' +
+			'  czm_material material = czm_getDefaultMaterial(materialInput);\n' +
+			'  vec2 st = materialInput.st;\n' +
+			'  vec3 str = materialInput.str;\n' +
+			'  float time1 = time * 2.0;\n' +
+			// '  material.diffuse = vec3(st.t,0.0,0.0);//materialInput.positionToEyeEC;\n' +
+			'  float time2 = time1;\n' +
+			'  if(time1 > 1.0){\n' +
+			'     time2 = (2.0 - time1);\n' +
+			'  }\n' +
+			'  if(st.t > time2 && st.t < time2 + 0.01){\n' +
+			'     material.diffuse = vec3(0.0,1.0,0.0)*1.5;\n' +
+			'  }else{\n' +
+			'     material.diffuse = vec3(0.0,0.0,1.0);\n' +
+			'  }\n' +
+			// '  if(st.t > time1 && st.t < time1 + 0.05){\n' +
+			// '     material.diffuse = color.rgb;\n' +
+			// '  }else{\n' +
+			// '     material.diffuse = vec3(0.0,0.0,1.0);\n' +
+			// '  }\n' +
+			// '  material.alpha = color.a * (1.0 - fract(str.r)) * 0.8;\n' +
+			'  return material;\n' +
+			'}';
+		return materail;
+	}
+}
+
+/* 重写方法 */
+Object.assign(LightMaterialProperty.prototype, {
+	/**
+	 * 重新获取类型方法
+	 * @param {Cesium.JulianDate} time 时间
+	 */
+	getType: function(time) {
+		return this._materialTypeName;
+	},
+
+	/**
+	 * 重写获取值方法
+	 * @param {Cesium.JulianDate} time
+	 * @param {JSON} result 
+	 */
+	getValue: function(time, result) {
+		if (!Cesium.defined(result)) {
+			result = {};
+		}
+		result.color = Cesium.Property.getValueOrClonedDefault(this._color, time, Cesium.Color.BLUE, result
+			.color);
+		if (this.duration) {
+			result.time = (((new Date()).getTime() - this._time) % this.duration) / this.duration;
+		}
+		this._viewer.scene.requestRender();
+		return result;
+	},
+
+	/**
+	 * 重写对比函数
+	 * @param {Object} other 传入对比对象
+	 */
+	equals: function(other) {
+		return (this === other || (other instanceof LightMaterialProperty && Cesium.Property.equals(this
+			._color, other._color)));
+	},
+})
+
+/* 默认属性 */
+Object.defineProperties(LightMaterialProperty.prototype, {
+	/**
+	 * 判断是否相等,返回false表示属性一直在变化中
+	 */
+	isConstant: {
+		get: function() {
+			return false;
+		}
+	},
+	/**
+	 * 事件变更
+	 */
+	definitionChanged: {
+		get: function() {
+			return this._definitionChanged;
+		}
+	},
+	/* 颜色属性 */
+	color: Cesium.createPropertyDescriptor('color')
+})
+
+/* 导出 */
+export default LightMaterialProperty;

+ 483 - 92
src/components/CrMap/SketchViewModel.js

@@ -14,6 +14,8 @@ import WallMaterialProperty from './WallMaterialProperty.js'
 /* 引入动态圆材质 */
 import CircleMaterialProperty from './CircleMaterialProperty.js'
 
+import LightMaterialProperty from './LightMaterialProperty.js'
+
 /* 扩展 Cesium.GroundPrimitive 给其添加objId属性*/
 
 /**
@@ -86,6 +88,21 @@ Cesium.Entity.prototype.getIsEdit = function() {
 }
 
 /**
+ * 设置附加参数
+ * @param {JSON} params 参数
+ */
+Cesium.Entity.prototype.setParams = function(params) {
+	this._params = params;
+}
+
+/**
+ * 获取附加参数
+ */
+Cesium.Entity.prototype.getParams = function() {
+	return this._params;
+}
+
+/**
  * 类
  */
 class SketchViewModel {
@@ -695,18 +712,53 @@ class SketchViewModel {
 				material: wallMaterial,
 			});
 
+			let fragmentShaderSource = 'varying vec3 v_positionEC;';
+			fragmentShaderSource += 'void main(void){\n' +
+				'  vec4 v_helsing_position = czm_inverseModelView * vec4(v_positionEC,1);\n' +
+				'  float _baseHeight = -30.0;\n' +
+				'  float vtxf_height = v_helsing_position.z - _baseHeight;\n' +
+				'  float stc_pl = fract(czm_frameNumber / 120.0) * 3.14159265 * 2.0;\n' +
+				'  float stc_sd = vtxf_height / 30.0 + sin(stc_pl) * 0.1;\n' +
+				'  gl_FragColor = vec4(1.0, 0.0, 0.0, 0.65);\n' +
+				'  gl_FragColor *= vec4(stc_sd, stc_sd, stc_sd, 1.0);\n' +
+				'  float glowRange = 80.0;\n' +
+				'  float stc_a13 = fract(czm_frameNumber / 460.0);\n' +
+				'  float stc_h = clamp(v_helsing_position.z / glowRange, 0.0, 1.0);\n' +
+				'  stc_a13 = abs(stc_a13 - 0.5) * 1.0;\n' +
+				'  float stc_diff = step(0.003, abs(stc_h - stc_a13));\n' +
+				// '  gl_FragColor.rgb += gl_FragColor.rgb * (1.0 - stc_diff);\n' +
+				'  float red = fract(czm_frameNumber / 460.0);\n' +
+				'  float l = sqrt(pow(v_helsing_position.x,2.0) + pow(v_helsing_position.y,2.0) + pow(v_helsing_position.z,2.0));\n' +
+				'  float cy3 = fract((abs(l - 100.0))/200.0);\n' +
+				'  if((cy3 - 0.1) < 0.0 ){\n' +
+				'     gl_FragColor = vec4(0.0,0.0,1.0,1.0);\n' +
+				'  }else{\n' +
+				'     gl_FragColor = vec4(1.0,0.0,0.0,1.0);\n' +
+				'  }\n' +
+				// '  if(v_helsing_position.z < 50000000.0){\n' +
+				// '     gl_FragColor = vec4(1.0,0.0,0.0,1.0);\n' +
+				// '  }else{\n' +
+				// '     gl_FragColor = vec4(0.0,0.0,1.0,1.0);\n' +
+				// '  }\n' +
+
+				// '  gl_FragColor = vec4(1.0,0.0,0.0,cy3*red);\n' +
+				'}\n';
+
 			/* 创建体的外观 */
 			let polygonAppearance = new Cesium.MaterialAppearance({
-				material: new Cesium.Material({
-					fabric: {
-						type: 'Color',
-						uniforms: {
-							color: _self._toColorFromArray(polygonColor),
-						}
-					}
-				}),
+				// material: new Cesium.Material({
+				// 	fabric: {
+				// 		type: 'Color',
+				// 		uniforms: {
+				// 			color: _self._toColorFromArray(polygonColor),
+				// 		}
+				// 	}
+				// }),
+				fragmentShaderSource: fragmentShaderSource,
 			});
 
+			console.log('===材质>>>', polygonAppearance.vertexShaderSource);
+
 			/* 设置墙的最小、最大高度 */
 			let wallMinimumHeights = [];
 			let wallMaximumHeights = [];
@@ -717,6 +769,7 @@ class SketchViewModel {
 			}
 			/* 追加第一个点 */
 			let height = parseFloat(_self._sketchOutputPoints[0].height);
+			console.log('===底面高度>>>', height);
 			wallMinimumHeights.push(height);
 			wallMaximumHeights.push(height + appendHeight);
 
@@ -1420,7 +1473,7 @@ class SketchViewModel {
 					positions: _self._sketchSpatialTrianglePositions,
 					material: _self._lineMaterial,
 					width: _self._param.lineWidth,
-					clampToGround: false, //为了绘制空间三角形 禁止贴地
+					clampToGround: false, //为了���������������制空�������三角形 禁止贴地
 				}
 			})
 			this._entities.add(this._sketchSpatialTriangle);
@@ -1428,7 +1481,7 @@ class SketchViewModel {
 	}
 
 	/**
-	 * 创建动态圆
+	 * 创������态圆
 	 * @param {Cesium.Cartesian3} centerPosition 圆的中心点位置
 	 */
 	_createDynamicCircle(centerPosition) {
@@ -1438,13 +1491,9 @@ class SketchViewModel {
 			viewer: _self._viewer,
 			duration: 2000,
 			color: _self._toColor(0, 255, 0, 0.6),
-			param: {
-				count: 3.0,
-				direction: 'horizontalA',
-				order: '-'
-			}
+			count: 1.0,
 		});
-		/* 储椭圆中心点位置 */
+		/* �����储椭圆中心点位置 */
 		this._sketchEllipseCenterPosition = centerPosition.clone();
 		/* 创建圆实体 */
 		let dynamicCircleEntity = new Cesium.Entity({
@@ -1465,7 +1514,7 @@ class SketchViewModel {
 	}
 
 	/**
-	 * 更动态圆
+	 * 更动态圆
 	 * @param {Boolean} isEdit [是否可编辑] 可选
 	 */
 	_updateDynamicCircle(isEdit) {
@@ -1481,6 +1530,53 @@ class SketchViewModel {
 	}
 
 	/**
+	 * 创建房屋
+	 * @param {Object} options
+	 */
+	_createHouse(options) {
+		let _self = this;
+		/* 体的高度 */
+		let appendHeight = parseFloat(100);
+		if (options && options.height && typeof options.height === 'number') appendHeight = parseFloat(options
+			.height);
+		let houseColor = 'rgba(0, 0, 255, 0.65)';
+		if (options && options.color) houseColor = options.color;
+		/* 创建体 */
+		if (!Cesium.defined(this._sketchPolygon)) {
+			/* 创建房屋的高度 */
+			let height = parseFloat(_self._sketchOutputPoints[0].height);
+			let houseHeight = height + appendHeight;
+			/* 创建一个房屋实体 */
+			let houseEntity = new Cesium.Entity({
+				name: _self._sketchEntityName,
+				polygon: {
+					show: true,
+					hierarchy: {
+						positions: _self._sketchPoints,
+					},
+					extrudedHeight: houseHeight,
+					material: _self._materialColorProperty({
+						color: houseColor,
+					}),
+				},
+			})
+			/* 添加要素 */
+			let entity = this._entities.add(houseEntity);
+			/* 附加属性 */
+			entity.setParams({
+				bottomHeight: height,
+				appendHeight: appendHeight,
+			});
+			/* 设置是否可编辑 */
+			if (options.isEdit != undefined && options.isEdit === true) {
+				/* 删除所有的临时点 忽略是否保留设置 */
+				this._removePointEntitys();
+				this._setEntityIsEdit(entity);
+			}
+		}
+	}
+
+	/**
 	 * 文字材质
 	 * @param {JSON} options 配置项
 	 * @param {String} options.text 文字内容 
@@ -1490,7 +1586,7 @@ class SketchViewModel {
 		this._canvasId = 'canvasJt';
 		/* 获取画布 */
 		let canvasObj = document.getElementById(this._canvasId);
-		/* 如果画�������已经存在则删除 */
+		/* 如果画已经存在则删除 */
 		if (canvasObj != null) {
 			document.body.removeChild(canvasObj);
 		}
@@ -1564,12 +1660,10 @@ class SketchViewModel {
 				text: '立体广告牌',
 			})
 		} else if (wallType !== undefined && wallType === SketchViewModel.SketchWallType.ColorWall) {
-			console.log("===>>>", '')
 			wallMaterial = this._materialColorProperty({
 				color: 'rgba(0,255,0,0.75)',
 			})
 		}
-		console.log('===>>>材质', wallMaterial);
 		/* 创建墙 */
 		let normalWall = new Cesium.Entity({
 			name: _self._sketchEntityName,
@@ -1704,7 +1798,7 @@ class SketchViewModel {
 
 	/**
 	 * 设置空间线样式
-	 * @param {JSON} options 配置���
+	 * @param {JSON} options 配置
 	 * @param {Array<Number>} options.color 线颜色[0~255,0~255,0~255,0~1]
 	 * @param {Number} options.lineWidth 移动线的宽度 
 	 * @param {Array<Number>} options.outlineColor 线描边颜色[0~255,0~255,0~255,0~1]
@@ -2837,7 +2931,7 @@ Object.assign(SketchViewModel.prototype, {
 			_self._removeEntityByObject(_self._sketchTempPolyline);
 			/* 绘制正式体 */
 			_self._createPolygonBody({
-				height: 30,
+				height: 100,
 				color: [255, 255, 0, 0.9],
 			});
 			/* 删除标记点 */
@@ -2979,6 +3073,89 @@ Object.assign(SketchViewModel.prototype, {
 	},
 
 	/**
+	 * 绘制不规则房屋
+	 * @param {Object} handler 事件句柄
+	 * @param {JSON} options 配置项
+	 * @param {Function} [options.onAdded(cPoints,gPoints)] 添加回调 可选
+	 * @param {Function} [options.onMoving(cPoint)] 移动回调 可选
+	 * @param {Function} [options.onUndo(cPoints)] 撤销回调 可选 
+	 * @param {Function} [options.onComplete(cPoints,gPoints)] 完成回调 可选
+	 * @param {Function} [options.onError(message)] 错误回到 可选
+	 */
+	_sketchDrawHouse(handler, options) {
+		let _self = this;
+		/* 注册鼠标左键点击事件 */
+		this._registerLeftClickEvent(handler, function(event) {
+			/* 识别屏幕位置 */
+			let loc = _self._transfromFromScreenPoint(event.position);
+			if (!Cesium.defined(loc.sLocation)) return;
+			/* 绘制点 */
+			if (_self._isDrawPoint) {
+				_self._createPoint(loc.sLocation, _self._lineLabel);
+			}
+			/* 第一点击的时候绘制线 */
+			if (_self._sketchTempPoints.length === 0) {
+				_self._createTempPolygon();
+				_self._createTempPolyline();
+				_self._sketchTempPoints.push(loc.sLocation.clone());
+			}
+			_self._sketchTempPoints.push(loc.sLocation);
+			/* 存储正式绘制点集合 */
+			_self._sketchPoints.push(loc.sLocation.clone());
+			/* 存储输出经纬度点集合 */
+			_self._sketchOutputPoints.push(loc.gLocation);
+			/* 监听输出 */
+			if (options.onAdded) options.onAdded(_self._sketchPoints, _self._sketchOutputPoints);
+		});
+		/* 注册鼠标移动事件 */
+		this._registerMouseMoveEvent(handler, function(event) {
+			/* 识别屏幕位置 */
+			let loc = _self._transfromFromScreenPoint(event.endPosition);
+			if (!Cesium.defined(loc.sLocation)) return;
+			if (Cesium.defined(_self._sketchTempPolygon)) {
+				_self._sketchTempPoints.pop();
+				_self._sketchTempPoints.push(loc.sLocation);
+				/* 监听输出 */
+				if (options.onMoving) options.onMoving(loc.sLocation);
+			}
+		});
+		/* 注册鼠标右键事件 */
+		this._registerRightClickEvent(handler, function(event) {
+			if (_self._sketchTempPoints.length > 2) {
+				/* 移除正式点最有一个元素 */
+				_self._sketchPoints.pop();
+				_self._sketchOutputPoints.pop();
+				/* 移除临时点倒数第二个元素 */
+				_self._sketchTempPoints.splice(_self._sketchTempPoints.length - 2, 1);
+				if (options.onUndo) options.onUndo(_self._sketchPoints);
+			}
+		});
+		/* 注册鼠标左键双击事件 */
+		this._registerLeftDoubleClickEvent(handler, function(event) {
+			if (_self._sketchPoints.length < 3) {
+				if (options.onError) options.onError('点数少于3个,禁止结束绘制!');
+				return;
+			}
+			/* 删除临时线和面 */
+			_self._removeEntityByObject(_self._sketchTempPolygon);
+			_self._removeEntityByObject(_self._sketchTempPolyline);
+			/* 绘制正式体 */
+			_self._createHouse({
+				height: 30,
+				color: 'rgba(0, 255, 0, 0.85)',
+				isEdit: options.isEdit,
+			});
+			/* 删除标记点 */
+			_self._removePointEntitys();
+			/* 干掉事件句柄 释放资源*/
+			_self._clearEvent(handler);
+			/* 监听输出 */
+			if (options.onComplete) options.onComplete(_self._sketchPoints, _self
+				._sketchOutputPoints);
+		})
+	},
+
+	/**
 	 * @param {SketchViewModel.SketchType} toolsType 草图工具类型
 	 * @param {JSON} options 回调集合
 	 * @param {Boolean} [isEdit] 是否可编辑 可选 设置可编辑将不在保留临时点 
@@ -3033,6 +3210,9 @@ Object.assign(SketchViewModel.prototype, {
 			case SketchViewModel.SketchType.DynamicCircle:
 				_self._sketchDrawDynamicCircle(_self._sketchEventHandler, options);
 				break;
+			case SketchViewModel.SketchType.House:
+				_self._sketchDrawHouse(_self._sketchEventHandler, options);
+				break;
 		}
 	},
 
@@ -3040,8 +3220,8 @@ Object.assign(SketchViewModel.prototype, {
 	 * 根据坐标绘制要素
 	 * @param {Array<Number>} points 点集合[lng,lat,......];
 	 * @param {SketchViewModel.SketchType} type 绘制类型
-	 * @param {JSON} options 回调配
-	 * @param {Function} options.onComplete() 完成回,可选
+	 * @param {JSON} options ���调���
+	 * @param {Function} options.onComplete() 完成回�������,可选
 	 * @param {Function} options.onError(message) 错误回调 
 	 */
 	sketchDrawFeacture: function(points, type, options) {
@@ -3078,14 +3258,14 @@ Object.assign(SketchViewModel.prototype, {
 				break;
 			case SketchViewModel.SketchType.DrawPolygon:
 				if (_self._sketchPoints.length < 3) {
-					if (options && options.onError) options.onError("点数少于3个,无法绘制!");
+					if (options && options.onError) options.onError("点数少���3���,无法绘���!");
 				} else {
 					_self._createPolygon();
 					if (options && options.onComplete) options.onComplete();
 				}
 				break;
 			default:
-				if (options && options.onError) options.onError("绘制类异常!");
+				if (options && options.onError) options.onError("绘制类�����异常!");
 				break;
 		}
 	},
@@ -3211,7 +3391,6 @@ Object.assign(SketchViewModel.prototype, {
 		let handler = new Cesium.ScreenSpaceEventHandler(this._viewer.scene.canvas);
 		this._registerLeftClickEvent(handler, function(event) {
 			let feature = _self._viewer.scene.pick(event.position);
-			console.log('===选中的要素', feature);
 			if (feature === undefined) {
 				_self._unActivateEdit();
 			} else {
@@ -3257,6 +3436,42 @@ Object.assign(SketchViewModel.prototype, {
 								text: '',
 							})
 						}
+					} else if (editEntityType === SketchViewModel.SketchEntityType.Circle) {
+						/* 获取绘制墙的材质 */
+						let material = feature.id.ellipse.material;
+						/* 获取参数 */
+						let param = feature.id.ellipse.material._param;
+						if (material instanceof CircleMaterialProperty) {
+							if (_self.onEditWall) _self.onEditWall({
+								id: 'DynamicCircleMaterial',
+								height: 0,
+								color: param.color,
+								count: param.count,
+								direction: 'v',
+								order: '-',
+								text: '',
+							})
+						}
+					} else if (editEntityType === SketchViewModel.SketchEntityType.Polygon) {
+						/* 分两种 一种是平面 一种是立体 */
+						let entityParams = feature.id.getParams();
+						if (entityParams !== undefined && entityParams.bottomHeight !== undefined) {
+							/* 获取绘制墙的材质 */
+							let material = feature.id.polygon.material;
+							/* 获取参数 */
+							let param = feature.id.polygon.material._param;
+							if (material instanceof Cesium.ColorMaterialProperty) {
+								if (_self.onEditWall) _self.onEditWall({
+									id: 'House',
+									height: entityParams.appendHeight,
+									color: param.color,
+									count: 0,
+									direction: 'v',
+									order: '-',
+									text: '',
+								})
+							}
+						}
 					}
 					_self._unActivateEdit();
 					_self._activateEdit(feature.id);
@@ -3271,48 +3486,81 @@ Object.assign(SketchViewModel.prototype, {
 	 * 更新当前编辑的实体墙/立体广告牌
 	 * @param {Object} params
 	 */
-	updateEditEntityWall: function(params) {
+	updateEditEntityProperty: function(params) {
 		let _self = this;
-		console.log('===最终传入的参数', params);
-		if (this._editEntity == undefined || this._editEntity.getEntityType() != SketchViewModel
-			.SketchEntityType.Wall) {
-			return;
-		}
-		let minHeights = this._editEntity.wall.minimumHeights._value;
-		let maxHeights = [];
-		for (let i = 0; i < minHeights.length; i++) {
-			maxHeights.push(minHeights[i] + parseFloat(params.height));
-		}
-		/* 设置墙的最大高度 */
-		this._editEntity.wall.maximumHeights = maxHeights;
-		/* 更改存储墙的最大高度的数组 */
-		this._sketchWallMaxHeights = maxHeights;
-		/* 根据传入的参数id判断需要搞什���材质 */
-		let wallMaterial = undefined;
-		if (params.id === 'TextMaterial') {
-			wallMaterial = this._materialTextImageProperty({
-				color: params.color,
-				text: params.text,
-			})
-		} else if (params.id === 'WallMaterial') {
-			wallMaterial = new WallMaterialProperty({
-				viewer: _self._viewer,
-				trailImage: '/img/image.png',
-				duration: 1500,
-				color: Cesium.Color.fromCssColorString(params.color),
-				param: {
+		/* 判断当前编辑的实体的类型 */
+		let editEntityType = this._editEntity.getEntityType();
+		if (editEntityType === SketchViewModel.SketchEntityType.Wall) {
+			let minHeights = this._editEntity.wall.minimumHeights._value;
+			let maxHeights = [];
+			for (let i = 0; i < minHeights.length; i++) {
+				maxHeights.push(minHeights[i] + parseFloat(params.height));
+			}
+			/* 设置墙的最大高度 */
+			this._editEntity.wall.maximumHeights = maxHeights;
+			/* 更改存储墙的最大高度的数组 */
+			this._sketchWallMaxHeights = maxHeights;
+			/* 根据传入的参数id判断需什么材质 */
+			let wallMaterial = this._editEntity.wall.material;
+			if (params.id === 'TextMaterial' && wallMaterial instanceof Cesium.ImageMaterialProperty) {
+				let material = this._materialTextImageProperty({
+					color: params.color,
+					text: params.text,
+				});
+				this._editEntity.wall.material = material;
+			} else if (params.id === 'WallMaterial' && wallMaterial instanceof WallMaterialProperty) {
+				let material = new WallMaterialProperty({
+					viewer: _self._viewer,
+					trailImage: '/img/image.png',
+					duration: 1500,
+					color: Cesium.Color.fromCssColorString(params.color),
+					param: {
+						count: parseFloat(params.count),
+						direction: params.direction,
+						order: params.order
+					}
+				});
+				this._editEntity.wall.material = material;
+			} else if (params.id === 'ColorMaterial' && wallMaterial instanceof Cesium
+				.ColorMaterialProperty) {
+				let material = this._materialColorProperty({
+					color: params.color,
+				});
+				this._editEntity.wall.material = material;
+			}
+		} else if (editEntityType === SketchViewModel.SketchEntityType.Circle) {
+			let circleMaterial = this._editEntity.ellipse.material;
+			if (circleMaterial instanceof CircleMaterialProperty) {
+				let material = new CircleMaterialProperty({
+					viewer: _self._viewer,
+					duration: 1500,
+					color: Cesium.Color.fromCssColorString(params.color),
 					count: parseFloat(params.count),
-					direction: params.direction,
-					order: params.order
+				});
+				this._editEntity.ellipse.material = material;
+			}
+		} else if (editEntityType === SketchViewModel.SketchEntityType.Polygon) {
+			let entityParams = this._editEntity.getParams();
+			if (entityParams !== undefined && entityParams.bottomHeight !== undefined) {
+				let polygonMaterial = this._editEntity.polygon.material;
+				if (params.id === 'House' && polygonMaterial instanceof Cesium
+					.ColorMaterialProperty) {
+					let material = this._materialColorProperty({
+						color: params.color,
+					});
+					/* 设置材质 */
+					this._editEntity.polygon.material = material;
+					/* 设置高度 */
+					this._editEntity.polygon.extrudedHeight = parseFloat(params.height) + parseFloat(
+						entityParams.bottomHeight);
+					/* 设置新的参数 */
+					this._editEntity.setParams({
+						bottomHeight: entityParams.bottomHeight,
+						appendHeight: params.height,
+					})
 				}
-			});
-		} else if (params.id === 'ColorMaterial') {
-			wallMaterial = this._materialColorProperty({
-				color: params.color,
-			})
+			}
 		}
-		this._editEntity.wall.material = wallMaterial;
-		console.log(this._editEntity);
 	},
 
 	/**
@@ -3329,16 +3577,29 @@ Object.assign(SketchViewModel.prototype, {
 			} else if (entity.polygon != undefined) {
 				entity.setEntityType(SketchViewModel.SketchEntityType.Polygon);
 				let positions = entity.polygon.hierarchy._value.positions;
-				positions.push(positions[0].clone());
+				/* 判断是否需要加上起点 */
+				if (positions[0].x !== positions[positions.length - 1].x) {
+					positions.push(positions[0].clone());
+				}
 				return positions;
 			} else if (entity.rectangle != undefined) {
 				entity.setEntityType(SketchViewModel.SketchEntityType.Rectangle);
 				let rect = entity.rectangle.coordinates._value;
 				/* 计算西北角的位置 */
-				let gNw = Cesium.Rectangle.northwest(rect); //Cartographic
+				let gNw = Cesium.Rectangle.northwest(rect);
+				if (gNw.height <= 0) {
+					let height = this._queryHeightFromGeo(Cesium.Math.toDegrees(gNw.longitude), Cesium.Math
+						.toDegrees(gNw.latitude));
+					gNw.height = height;
+				}
 				let cNw = Cesium.Cartesian3.fromRadians(gNw.longitude, gNw.latitude, gNw.height);
 				/* 计算东南角位置 */
 				let gSe = Cesium.Rectangle.southeast(rect);
+				if (gSe.height <= 0) {
+					let height = this._queryHeightFromGeo(Cesium.Math.toDegrees(gSe.longitude), Cesium.Math
+						.toDegrees(gSe.latitude));
+					gSe.height = height;
+				}
 				let cSe = Cesium.Cartesian3.fromRadians(gSe.longitude, gSe.latitude, gSe.height);
 				/* 组合坐标数组 */
 				return [cNw, cSe];
@@ -3352,7 +3613,7 @@ Object.assign(SketchViewModel.prototype, {
 				return [centerPosition, cbPoint];
 			} else if (entity.wall != undefined) {
 				entity.setEntityType(SketchViewModel.SketchEntityType.Wall);
-				/* 存储墙���最大高度���最小高度数组 */
+				/* 存储墙的最大高度和最小高度数组 */
 				this._sketchWallHeights = [];
 				this._sketchWallMaxHeights = [];
 				let minHeights = entity.wall.minimumHeights._value;
@@ -3442,9 +3703,15 @@ Object.assign(SketchViewModel.prototype, {
 		let point = turf.point([geoPoint.longitude, geoPoint.latitude]);
 		let resPoint = turf.destination(point, distance, bearing, options).geometry
 			.coordinates;
+		/* 根据经纬度查询高度 该步骤耗时 且容易出错 */
+		let height = 0;
+		if (options !== undefined && options.calculateHeight !== undefined && options.calculateHeight ===
+			true) {
+			height = this._queryHeightFromGeo(resPoint[0], resPoint[1]);
+		}
 		/* 将移动后的点转换为世界坐标系坐标点 */
 		let cPosition = Cesium.Cartesian3.fromDegrees(resPoint[0], resPoint[1],
-			0);
+			height);
 		/* 返回 */
 		return cPosition;
 	},
@@ -3461,8 +3728,10 @@ Object.assign(SketchViewModel.prototype, {
 	 * @param {Cesium.Entity} editEntity 编辑实体
 	 */
 	_activateEdit: function(editEntity) {
+		/* 打印当前编辑的实体 */
+		console.log('===当前编辑的实体>>>', editEntity);
 		let _self = this;
-		/* 设置实体类型 */
+		/* 设置实体类型 返回该实体用于绘制的点集合*/
 		let positions = this._setEntityType(editEntity);
 		/* 获取编辑类型 */
 		let entityType = editEntity.getEntityType();
@@ -3485,7 +3754,7 @@ Object.assign(SketchViewModel.prototype, {
 			this._createEditCenterPoint(centerPosition);
 		}
 		/* 创建中点 */
-		if (entityType != SketchViewModel.SketchEntityType.Rectangle && entityType != SketchViewModel
+		if (entityType !== SketchViewModel.SketchEntityType.Rectangle && entityType !== SketchViewModel
 			.SketchEntityType.Circle && entityType !== SketchViewModel.SketchEntityType.DynamicCircle) {
 			this._createEditMiddlePoint(positions);
 		}
@@ -3579,6 +3848,14 @@ Object.assign(SketchViewModel.prototype, {
 					let editEntityType = _self._editEntity.getEntityType();
 					if (editEntityType != SketchViewModel.SketchEntityType.Rectangle &&
 						editEntityType != SketchViewModel.SketchEntityType.Circle) {
+						/* 这里对面对象需要进行特殊处理 保证第0号点和最后一个点是一致的 */
+						if (editEntityType === SketchViewModel.SketchEntityType.Polygon && _self
+							._sketchEditIndex === 0) {
+							_self._sketchEditPoints[_self._sketchEditPoints.length - 1] = loc
+								.sLocation;
+						} else if (editEntityType === SketchViewModel.SketchEntityType.Wall) {
+							_self._sketchWallHeights[_self._sketchEditIndex] = loc.gLocation.height;
+						}
 						/* 移除所有中点 */
 						_self._removeEntityByName(_self._sketchEditEntityMiddleName);
 						/* 创建所有中点 */
@@ -3596,7 +3873,6 @@ Object.assign(SketchViewModel.prototype, {
 					let bottomPoint = _self._sketchEditPoints[_self._sketchEditIndex];
 					/* 计算高差 */
 					let heightDifference = cartesian.z - bottomPoint.z;
-					console.log("===高度差", heightDifference);
 					if (heightDifference > 0 && heightDifference < 500) {
 						for (let i = 0; i < _self._sketchWallHeights.length; i++) {
 							_self._sketchWallMaxHeights[i] = _self._sketchWallHeights[i] +
@@ -3624,7 +3900,7 @@ Object.assign(SketchViewModel.prototype, {
 					/* 处理鼠标抬起实体的属性变更回调 */
 					_self._entityCallbackPropertyByMouseUp();
 				} else if (editEntityPointType === SketchViewModel.SketchEditType.Center) {
-					_self._entityCenterMouseUpEvent();
+					_self._entityCenterMouseUpEvent(event);
 				}
 				/* 删除节点、中点和中心点 */
 				_self._removeEntityByName(_self._sketchEditEntityNodeName);
@@ -3644,7 +3920,9 @@ Object.assign(SketchViewModel.prototype, {
 					SketchViewModel.SketchEntityType.Polyline || entityType === SketchViewModel
 					.SketchEntityType.Rectangle || entityType === SketchViewModel.SketchEntityType
 					.Wall) {
+					/* 创建节点 */
 					_self._createEditNodePoint(_self._sketchEditPoints);
+					/* 创建中心点 */
 					let centerPosition = _self._calculateCenterPosition(_self._sketchEditPoints);
 					_self._createEditCenterPoint(centerPosition);
 					/* 如果当前编辑的是墙 还要创建空中点 */
@@ -3665,7 +3943,7 @@ Object.assign(SketchViewModel.prototype, {
 	},
 
 	/**
-	 * 实体中心点鼠标按下
+	 * 实体中心点鼠标按下(拖拽点按下)
 	 */
 	_entityCenterMouseDownEvent: function() {
 		let _self = this;
@@ -3744,18 +4022,30 @@ Object.assign(SketchViewModel.prototype, {
 	 * @param {Cesium.Event} event 事件
 	 */
 	_entityCenterMouseMoveEvent: function(event) {
+		this._calculatePositionsByCenter(event.endPosition, false);
+	},
+
+	/* 换个思路试试 移动过程中不计算 待移动完成后计算 以便保证移动速度 要不实时计算高度 导致卡顿 */
+
+	/**
+	 * 计算中心拖拽点移动后实体点随之移动后的位置数据
+	 * @param {JSON} screenPosition 移动后的屏幕点
+	 * @param {Boolean} calculateHeight 是否计算移动点的高度
+	 */
+	_calculatePositionsByCenter: function(screenPosition, calculateHeight) {
 		let _self = this;
-		/* 将移动的起始点转换为经纬度 */
-		let strLoc = this._cartesian3ToGeo(_self._startPoint);
-		/* 获取移动的种植点 */
-		let endLoc = this._transfromFromScreenPoint(event.endPosition);
+		/* 将起始点转换为经纬度 */
+		let strLoc = this._cartesian3ToGeo(this._startPoint);
+		/* 获取终止点 */
+		let endLoc = this._transfromFromScreenPoint(screenPosition);
 		/* 计算两点之间的角度 */
 		var point1 = turf.point([strLoc.longitude, strLoc.latitude]);
 		var point2 = turf.point([endLoc.gLocation.lng, endLoc.gLocation.lat]);
 		var bearing = turf.bearing(point1, point2);
-		/* 计算亮点之间的距离 */
+		/* 计算亮点之间的距离 距离单位和是否计算高度*/
 		var options = {
-			units: 'kilometers'
+			units: 'kilometers',
+			calculateHeight: calculateHeight
 		};
 		var distance = turf.distance(point1, point2, options);
 		/* 根据移动的不同类型实体进行不同的操作 */
@@ -3787,9 +4077,12 @@ Object.assign(SketchViewModel.prototype, {
 	},
 
 	/**
-	 * 实体中心点鼠标抬起
+	 * 实体中心点鼠标抬起(即拖拽点)
+	 * @param {Object} event 事件
 	 */
-	_entityCenterMouseUpEvent: function() {
+	_entityCenterMouseUpEvent: function(event) {
+		/* 计算最新位置点 */
+		this._calculatePositionsByCenter(event.position, true);
 		let _self = this;
 		/* 根据不同的实体进行不同的操作 */
 		let editEntityType = this._editEntity.getEntityType();
@@ -3834,7 +4127,17 @@ Object.assign(SketchViewModel.prototype, {
 			};
 			/* 此处需要特殊处理一下 */
 			if (_self._editEntity.polyline != undefined) {
-				_self._editEntity.polyline.positions = _self._sketchEditPoints;
+				/* 如果创建区域的同时 创建了边界线 则根据区域的边界创建线 */
+				let polygonPositions = _self._editEntity.polygon.hierarchy._value.positions;
+				let linePositions = [];
+				for (let i = 0; i < polygonPositions.length; i++) {
+					linePositions.push(polygonPositions[i].clone());
+				}
+				/* 判断是否需要加入0号点 */
+				if (linePositions[0].x !== linePositions[linePositions.length - 1].x) {
+					linePositions.push(linePositions[0].clone());
+				}
+				_self._editEntity.polyline.positions = linePositions;
 			}
 		} else if (entityType === SketchViewModel.SketchEntityType.Rectangle) {
 			_self._editEntity.rectangle.coordinates = Cesium.Rectangle.fromDegrees(_self
@@ -3854,9 +4157,6 @@ Object.assign(SketchViewModel.prototype, {
 				_self._editEntity.polyline.positions = _self._ellipseOutlineCoordinates;
 			}
 		} else if (entityType === SketchViewModel.SketchEntityType.Wall) {
-			/* 测试一下 */
-			console.log("===", '底部点数', _self._sketchEditPoints.length, '最小高度点数', _self._sketchWallHeights
-				.length, '最大高度点数', _self._sketchWallMaxHeights.length);
 			_self._editEntity.wall.positions = _self._sketchEditPoints;
 			_self._editEntity.wall.minimumHeights = _self._sketchWallHeights;
 			_self._editEntity.wall.maximumHeights = _self._sketchWallMaxHeights;
@@ -3886,7 +4186,17 @@ Object.assign(SketchViewModel.prototype, {
 			if (_self._editEntity.polyline != undefined) {
 				_self._editEntity.polyline.positions = new Cesium.CallbackProperty(
 					function() {
-						return _self._sketchEditPoints;
+						/* 如果创建区域的同时 创建了边界线 则根据区域的边界创建线 */
+						let polygonPositions = _self._sketchEditPoints;
+						let linePositions = [];
+						for (let i = 0; i < polygonPositions.length; i++) {
+							linePositions.push(polygonPositions[i].clone());
+						}
+						/* 判断是否需要加入0号点 */
+						if (linePositions[0].x !== linePositions[linePositions.length - 1].x) {
+							linePositions.push(linePositions[0].clone());
+						}
+						return linePositions;
 					}, false);
 			}
 		} else if (entityType === SketchViewModel.SketchEntityType.Rectangle) {
@@ -3963,7 +4273,8 @@ Object.assign(SketchViewModel.prototype, {
 				color: _self._toColorFromArray(color),
 				outlineWidth: outlineWidth,
 				outlineColor: _self._toColorFromArray(outlineColor),
-				disableDepthTestDistance: 1.5e12, //小于该数值后关闭深度检测�������默认为空
+				disableDepthTestDistance: 1.5e12, //小于该数值后关闭深度检测默认为空
+				// heightReference: Cesium.HeightReference.CLAMP_TO_GROUND,
 			},
 		})
 		/* 这是类型 */
@@ -3991,10 +4302,22 @@ Object.assign(SketchViewModel.prototype, {
 			this._sketchEditPoints.push(position.clone());
 			/* 小于索引不会创建 */
 			if (i < strIndex) continue;
+			/* 为了保证不重复创建节点 需要进行特殊过滤处理 */
+			if (i !== 0 && position.x === positions[0].x && position.y === positions[0].y && position.z ===
+				positions[0]
+				.z) {
+				continue;
+			}
+			/* 创建节点前 特殊处理一下 以保证创建的节点 高度是正确的 */
+			let geoPoint = this._cartesian3ToGeo(position);
+			/* 查询高度 */
+			let height = this._queryHeightFromGeo(geoPoint.longitude, geoPoint.latitude);
+			/* 创建新位置 */
+			let newPosition = Cesium.Cartesian3.fromDegrees(geoPoint.longitude, geoPoint.latitude, height);
 			/* 创建实体 */
-			this._createEditPointEntity({
+			_self._createEditPointEntity({
 				name: _self._sketchEditEntityNodeName,
-				position: position,
+				position: newPosition,
 				size: 12,
 				color: [0, 0, 255, 1.0],
 				editType: {
@@ -4083,7 +4406,9 @@ Object.assign(SketchViewModel.prototype, {
 			name: _self._sketchEditEntityCenterName,
 			position: position,
 			size: 12,
-			color: [0, 255, 0, 1.0],
+			color: [0, 255, 0, 0.1],
+			outlineWidth: 2.0,
+			outlineColor: [255, 255, 255, 1.0],
 			editType: {
 				type: SketchViewModel.SketchEditType.Center,
 			},
@@ -4142,10 +4467,35 @@ Object.assign(SketchViewModel.prototype, {
 		let rLng = Cesium.Math.toRadians(longitude);
 		let rLat = Cesium.Math.toRadians(latitude);
 		let cartographic = new Cesium.Cartographic(rLng, rLat);
-		let height = this._viewer.scene.sampleHeight(cartographic);
+		/* 获取不采样的实体数组 */
+		let noQueryEntities = [];
+		for (let i = 0; i < this._entities.values.length; i++) {
+			if (this._entities.values[i].name === this._sketchEntityName) {
+				noQueryEntities.push(this._entities.values[i]);
+			}
+		}
+		let height = this._viewer.scene.sampleHeight(cartographic, noQueryEntities);
 		if (height === undefined) return 0
 		else return height;
 	},
+
+	/**
+	 * 查询指定经纬度位置的高度 有地形则查地形 有模型则查模型 查询错误或未查询到,返回0
+	 * @param {Number} longitude 经度<度格式>
+	 * @param {Number} latitude 纬度<度格式>
+	 * @param {Function} callComplete 查询回调函数callComplete(Number) 查询错误时为undefined
+	 */
+	_queryHeightFromGeoAsync: function(longitude, latitude, callComplete) {
+		if (longitude === undefined || latitude === undefined || typeof longitude != 'number' ||
+			typeof latitude != 'number') return 0;
+		let rLng = Cesium.Math.toRadians(longitude);
+		let rLat = Cesium.Math.toRadians(latitude);
+		let cartographic = new Cesium.Cartographic(rLng, rLat);
+		let promise = this._viewer.scene.sampleHeightMostDetailed([cartographic]);
+		promise.then(function(updatedPositions) {
+			if (callComplete) callComplete(updatedPositions[0].height);
+		})
+	},
 	/**
 	 * 清理编辑点
 	 */
@@ -4167,6 +4517,46 @@ Object.assign(SketchViewModel.prototype, {
 	},
 })
 
+/**
+ * 高度查询相关函数
+ */
+Object.assign(SketchViewModel.prototype, {
+	/**
+	 * 异步查询高度 准确度高
+	 * @param {Array<Cesium.Cartesian3>} positions 位置结合
+	 * @param {Function} callComplete 完成回调 callComplete(Array<Cesium.Cartesian3>)
+	 */
+	_clampToHeightMostDetailed: function(positions, callComplete) {
+		let promise = this._viewer.scene.clampToHeightMostDetailed(positions);
+		promise.then(function(updatePositions) {
+			if (callComplete) callComplete(updatePositions);
+		})
+	},
+
+	/**
+	 * 异步查询高度 准确度高
+	 * @param {Array<Cesium.Cartesian3>} positions 位置结合
+	 * @param {Function} callComplete 完成回调 callComplete(Array<Cesium.Cartesian3>)
+	 */
+	_sampleHeightMostDetailed: function(positions, callComplete) {
+		let cartographics = [];
+		for (let i = 0; i < positions.length; i++) {
+			cartographics.push(this._viewer.scene.globe.ellipsoid.cartesianToCartographic(positions[i]));
+		}
+		let promise = this._viewer.scene.sampleHeightMostDetailed(cartographics);
+		promise.then(function(updatePositions) {
+			let resultPositions = [];
+			for (let i = 0; i < cartographics.length; i++) {
+				let cartesian = Cesium.Cartesian3.fromRadians(cartographics[i].longitude,
+					cartographics[i].latitude, updatePositions[i].height);
+				resultPositions.push(cartesian);
+			}
+			if (callComplete) callComplete(resultPositions);
+		})
+	},
+
+});
+
 /* 编辑函数相关 */
 Object.assign(SketchViewModel.prototype, {
 	/**
@@ -4317,6 +4707,7 @@ SketchViewModel.SketchType = Object.freeze({
 	Wall: 'wall',
 	Triangle: 'triangle',
 	PolygonBody: 'polygonBody',
+	House: 'house',
 	DrawPoint: 'drawPoint',
 	DrawMultiplePoint: 'drawMultiplePoint',
 	DrawPolyline: 'drawPolyline',

+ 1 - 1
src/components/CrMap/WallMaterialProperty.js

@@ -54,7 +54,7 @@ class WallMaterialProperty {
 					color: new Cesium.Color(1.0, 0.0, 0.0, 0.5),
 					image: options.trailImage,
 				},
-				source: _getDirectionWallShader(options.param)
+				source: this._getDirectionWallShader(options.param)
 			},
 			translucent: function(material) {
 				/* 材质是否半透明 */

+ 63 - 20
src/components/jt-dialog/dialog-wall-edit.vue → src/components/jt-dialog/dialogEditProperty.vue

@@ -18,7 +18,7 @@
 
 			<template #default>
 				<div class="odin-dialog__content">
-					<div class="jt-wall-row">
+					<div class="jt-wall-row" v-show="isShowHeight">
 						<div class="col-left">高度</div>
 						<div class="col-main"><el-input v-model="wallHeight" placeholder="输入高度值" clearable /></div>
 					</div>
@@ -26,7 +26,7 @@
 						<div class="col-left">颜色</div>
 						<div class="col-main"><el-color-picker v-model="color" show-alpha :predefine="predefineColors" /></div>
 					</div>
-					<div class="jt-wall-row" v-show="isWallMaterial">
+					<div class="jt-wall-row" v-show="isShowDirection">
 						<div class="col-left">材质方向</div>
 						<div class="col-main">
 							<el-radio-group v-model="radioDirection">
@@ -34,17 +34,17 @@
 							</el-radio-group>
 						</div>
 					</div>
-					<div class="jt-wall-row" v-show="isWallMaterial">
+					<div class="jt-wall-row" v-show="isShowOrder">
 						<div class="col-left">流动顺序</div>
 						<div class="col-main">
 							<el-radio-group v-model="radioOrder"><el-radio-button v-for="(item, index) in orders" :label="item.key" v-model="item.value" /></el-radio-group>
 						</div>
 					</div>
-					<div class="jt-wall-row" v-show="isWallMaterial">
+					<div class="jt-wall-row" v-show="isShowCount">
 						<div class="col-left">重复数量</div>
 						<div class="col-main"><el-input v-model="yCount" placeholder="输入1~100" clearable /></div>
 					</div>
-					<div class="jt-wall-row" v-show="isTextMaterial" style="height: 60px;">
+					<div class="jt-wall-row" v-show="isShowText" style="height: 60px;">
 						<div class="col-left">文字内容</div>
 						<div class="col-main"><el-input v-model="txtContent" placeholder="输入显示的文字内容" clearable type="textarea" :rows="2" /></div>
 					</div>
@@ -65,6 +65,7 @@ import { ref, reactive, toRefs, watch } from 'vue';
 import { ElDialog } from 'element-plus';
 import { ArrowLeft, ArrowRight, Delete, Edit, Share } from '@element-plus/icons-vue';
 import { param } from 'jquery';
+import { DrawTools } from '../CrMap/DrawTools.js';
 const props = defineProps({
 	params: {
 		id: {
@@ -120,10 +121,13 @@ const predefineColors = ref([
 	'#c7158577'
 ]);
 /* 初始赋值 */
-const isTextMaterial = ref(false);
-const isWallMaterial = ref(false);
+const isShowText = ref(false);
+const isShowHeight = ref(false);
+const isShowDirection = ref(false);
+const isShowOrder = ref(false);
+const isShowCount = ref(false);
 const color = ref(props.params.color);
-const title = ref('立体墙属性');
+const title = ref('属性编辑');
 const dialogVisible = ref(props.showDialog);
 const directions = reactive([{ key: '左右', value: 'horizontal' }, { key: '上下', value: 'vertical' }]);
 const orders = reactive([]);
@@ -152,21 +156,60 @@ watch(props.params, (newVal, oldVal) => {
  */
 function updateParams(params) {
 	/* 根据参数的显示不同的内容 */
-	if (params.id === 'TextMaterial') {
-		isTextMaterial.value = true;
-		isWallMaterial.value = false;
-	} else if (params.id === 'WallMaterial') {
-		isTextMaterial.value = false;
-		isWallMaterial.value = true;
+	if (params.id === DrawTools.DrawType.TextWall) {
+		title.value = '广告牌编辑';
+		isShowText.value = true;
+		isShowDirection.value = false;
+		isShowOrder.value = false;
+		isShowCount.value = false;
+		isShowHeight.value = true;
+	} else if (params.id === DrawTools.DrawType.DynamicWall) {
+		title.value = '动态围栏编辑';
+		isShowText.value = false;
+		isShowDirection.value = true;
+		isShowOrder.value = true;
+		isShowCount.value = true;
+		isShowHeight.value = true;
+	} else if (params.id === DrawTools.DrawType.NormalWall) {
+		title.value = '普通围栏编辑';
+		isShowText.value = false;
+		isShowDirection.value = false;
+		isShowOrder.value = false;
+		isShowCount.value = false;
+		isShowHeight.value = true;
+	} else if (params.id === DrawTools.DrawType.Circle) {
+		title.value = '贴地圆编辑';
+		isShowText.value = false;
+		isShowDirection.value = false;
+		isShowOrder.value = false;
+		isShowCount.value = false;
+		isShowHeight.value = false;
+	} else if (params.id === DrawTools.DrawType.DynamicCircle) {
+		title.value = '扩散圆编辑';
+		isShowText.value = false;
+		isShowDirection.value = false;
+		isShowOrder.value = false;
+		isShowCount.value = true;
+		isShowHeight.value = false;
+	} else if (params.id === DrawTools.DrawType.House) {
+		title.value = '房屋编辑';
+		isShowText.value = false;
+		isShowDirection.value = false;
+		isShowOrder.value = false;
+		isShowCount.value = false;
+		isShowHeight.value = true;
 	} else {
-		isTextMaterial.value = false;
-		isWallMaterial.value = false;
+		isShowText.value = false;
+		isShowDirection.value = false;
+		isShowOrder.value = false;
+		isShowCount.value = false;
+		isShowHeight.value = false;
 	}
 	color.value = params.color;
 	/* 判断方向及顺序 */
 	if (params.direction === 'horizontal') {
 		radioDirection.value = directions[0].key;
-		Object.assign(orders, [{ key: '自左至右', value: '+' }, { key: '自右至左', value: '-' }]);
+		Object.assign(orders, [{ key: '自左至右', value: '-' }, { key: '自右至左', value: '+' }]);
 		if (params.order === '+') {
 			radioOrder.value = orders[0].key;
 		} else {
@@ -174,7 +217,7 @@ function updateParams(params) {
 		}
 	} else {
 		radioDirection.value = directions[1].key;
-		Object.assign(orders, [{ key: '自上至下', value: '+' }, { key: '自下至上', value: '-' }]);
+		Object.assign(orders, [{ key: '自上至下', value: '-' }, { key: '自下至上', value: '+' }]);
 		if (params.order === '+') {
 			radioOrder.value = orders[0].key;
 		} else {
@@ -219,10 +262,10 @@ function submit() {
  */
 function directionChange(e) {
 	if (e.target.value === directions[0].key) {
-		Object.assign(orders, [{ key: '自左至右', value: '+' }, { key: '自右至左', value: '-' }]);
+		Object.assign(orders, [{ key: '自左至右', value: '-' }, { key: '自右至左', value: '+' }]);
 		radioOrder.value = orders[0].key;
 	} else if (e.target.value === directions[1].key) {
-		Object.assign(orders, [{ key: '自上至下', value: '+' }, { key: '自下至上', value: '-' }]);
+		Object.assign(orders, [{ key: '自上至下', value: '-' }, { key: '自下至上', value: '+' }]);
 		radioOrder.value = orders[0].key;
 	}
 }

+ 44 - 33
src/pages/tab-cmap.vue

@@ -1,5 +1,5 @@
 <template>
-	<CrMap ref="cmap" @onEditWall="onEditWall"></CrMap>
+	<CrMap ref="cmap" @onEditProperty="onEditProperty"></CrMap>
 	<view class="cr-tools-left">
 		<ToolButton v-for="(item, index) in leftTools" :id="item.id" :title="item.title" :describe="item.describe" :icon="item.icon" @onclick="onToolsClick" />
 	</view>
@@ -44,7 +44,7 @@
 			</div>
 		</div>
 	</van-popup>
-	<jtDialog class="jt-tools-dialog" :showDialog="showDialog" title="地图标绘" height="500px" width="300px" @closeJTDialog="closeDialog">
+	<jtDialog class="jt-tools-dialog" :showDialog="showDialog" title="地图标绘" height="550px" width="300px" @closeJTDialog="closeDialog">
 		<el-row :gutter="20">
 			<el-col :span="8" @click="this.$refs['cmap'].onMouseDrawEditLine()">
 				<el-avatar shape="circle" :size="50" style="background-color: bisque;"><i class="app-icon app-icon-draw-line" /></el-avatar>
@@ -66,18 +66,18 @@
 			</el-col>
 			<el-col :span="8" @click="this.$refs['cmap'].onMouseDrawEditCircle()">
 				<el-avatar shape="circle" :size="50" style="background-color: azure;"><i class="app-icon app-icon-draw-circle" /></el-avatar>
-				<cite>圆</cite>
+				<cite>贴地圆</cite>
 			</el-col>
 			<el-col :span="8" @click="this.$refs['cmap'].onMouseDrawDynamicEditWall()">
 				<el-avatar shape="circle" :size="50" style="background-color: bisque;"><i class="app-icon app-icon-draw-dwall" /></el-avatar>
-				<cite>动态</cite>
+				<cite>动态围栏</cite>
 			</el-col>
 		</el-row>
 
 		<el-row :gutter="20">
 			<el-col :span="8" @click="this.$refs['cmap'].onMouseDrawColorEditWall()">
 				<el-avatar shape="circle" :size="50" style="background-color: bisque;"><i class="app-icon app-icon-draw-wall" /></el-avatar>
-				<cite>普通</cite>
+				<cite>普通围栏</cite>
 			</el-col>
 			<el-col :span="8" @click="this.$refs['cmap'].onMouseDrawEditText()">
 				<el-avatar shape="circle" :size="50" style="background-color: azure;"><i class="app-icon app-icon-draw-text" /></el-avatar>
@@ -85,34 +85,48 @@
 			</el-col>
 			<el-col :span="8" @click="this.$refs['cmap'].onMouseDrawDynamicCircle()">
 				<el-avatar shape="circle" :size="50" style="background-color: bisque;"><i class="app-icon app-icon-draw-circle" /></el-avatar>
-				<cite>动态圆</cite>
+				<cite>扩散圆</cite>
 			</el-col>
 		</el-row>
 		<el-row :gutter="20">
-			<el-col :span="8" @click="this.$refs['cmap'].onMouseDrawColorEditWall()">
-				<el-avatar shape="circle" :size="50" style="background-color: bisque;"><i class="app-icon app-icon-draw-wall" /></el-avatar>
-				<cite>普通墙11</cite>
+			<el-col :span="8" @click="this.$refs['cmap'].onMoouseDrawPolygonBody()">
+				<el-avatar shape="circle" :size="50" style="background-color: bisque;"><i class="app-icon app-icon-draw-house" /></el-avatar>
+				<cite>房屋</cite>
 			</el-col>
 			<el-col :span="8" @click="this.$refs['cmap'].onMouseDrawEditText()">
-				<el-avatar shape="circle" :size="50" style="background-color: azure;"><i class="app-icon app-icon-draw-text" /></el-avatar>
-				<cite>广告牌11</cite>
+				<el-avatar shape="circle" :size="50" style="background-color: azure;"><i class="app-icon app-icon-draw-line" /></el-avatar>
+				<cite>箭头线</cite>
+			</el-col>
+			<el-col :span="8" @click="this.$refs['cmap'].onClearDraw()">
+				<el-avatar shape="circle" :size="50" style="background-color: bisque;"><i class="app-icon app-icon-draw-line" /></el-avatar>
+				<cite>流动线</cite>
+			</el-col>
+		</el-row>
+		<el-row :gutter="20">
+			<el-col :span="8" @click="this.$refs['cmap'].onMoouseDrawPolygonBody()">
+				<el-avatar shape="circle" :size="50" style="background-color: bisque;"><i class="app-icon app-icon-draw-line" /></el-avatar>
+				<cite>发光线</cite>
+			</el-col>
+			<el-col :span="8" @click="this.$refs['cmap'].onMouseDrawEditText()">
+				<el-avatar shape="circle" :size="50" style="background-color: azure;"><i class="app-icon app-icon-draw-line" /></el-avatar>
+				<cite>描边线</cite>
 			</el-col>
 			<el-col :span="8" @click="this.$refs['cmap'].onClearDraw()">
 				<el-avatar shape="circle" :size="50" style="background-color: bisque;"><i class="app-icon app-icon-map-clean" /></el-avatar>
-				<cite>清除绘制</cite>
+				<cite>清除全部</cite>
 			</el-col>
 		</el-row>
 	</jtDialog>
 
 	<!-- 墙的编辑框 -->
-	<jtWallDialog ref="wallEditDialog" :params="wallparam" @submit="submit" v-model:showDialog="showWallDialog"></jtWallDialog>
+	<dialogEditProperty ref="dialogEdit" :params="editParams" @submit="submit" v-model:showDialog="showEditDialog"></dialogEditProperty>
 </template>
 <script setup>
 import { Dialog } from 'vant';
 /* 引入弹出对话框 */
 import jtDialog from '../components/jt-dialog/dialog.vue';
 /* 引入墙的编辑对话框 */
-import jtWallDialog from '../components/jt-dialog/dialog-wall-edit.vue';
+import dialogEditProperty from '../components/jt-dialog/dialogEditProperty.vue';
 </script>
 <script>
 /* 引入三维地图控件 */
@@ -141,7 +155,7 @@ export default {
 			height: 120,
 			dialogVisible: false,
 			showDialog: false,
-			wallparam: {
+			editParams: {
 				id: undefined,
 				height: 20,
 				color: 'rgba(255,0,255,0.8)',
@@ -150,7 +164,7 @@ export default {
 				count: 2,
 				text: ''
 			},
-			showWallDialog: false
+			showEditDialog: false
 		};
 	},
 	/* 创建 */
@@ -303,9 +317,7 @@ export default {
 					_self.$refs['cmap'].onQueryByPolygon();
 					break;
 				case 'queryByPoint':
-					// _self.$refs['cmap'].onQueryByPoint();
-					_self.showWallDialog = true;
-					console.log(this.showWallDialog);
+					_self.$refs['cmap'].onQueryByPoint();
 					break;
 				case 'queryByMultiplePoint':
 					_self.$refs['cmap'].onQueryByMultiplePoint();
@@ -395,29 +407,28 @@ export default {
 		 * 墙的编辑调用
 		 * @param {JSON} param 传递的编辑参数
 		 */
-		onEditWall(param) {
+		onEditProperty(param) {
+			console.log('===传递参数,打开编辑框>>>', param);
 			/* 打开对话框 */
-			this.showWallDialog = true;
+			this.showEditDialog = true;
 			/* 赋值参数 */
-			this.wallparam.id = param.id;
-			this.wallparam.color = param.color;
-			this.wallparam.count = param.count;
-			this.wallparam.height = param.height;
-			this.wallparam.direction = param.direction;
-			this.wallparam.order = param.order;
-			this.wallparam.text = param.text;
-			/* 更新显示 */
-			this.$refs['wallEditDialog'].updateParams(this.wallparam);
-			console.log('======>>>>>>>>>>>>', param);
+			this.editParams.id = param.id;
+			this.editParams.color = param.color;
+			this.editParams.count = param.count;
+			this.editParams.height = param.height;
+			this.editParams.direction = param.direction;
+			this.editParams.order = param.order;
+			this.editParams.text = param.text;
+			this.$refs['dialogEdit'].updateParams(this.editParams);
 		},
 
 		/**
-		 * 提交更改
+		 * 实体属性提交更改
 		 * @param {JSON} param 参数
 		 */
 		submit(param) {
 			console.log(param);
-			this.$refs['cmap'].onSubmitEditWall(param);
+			this.$refs['cmap'].onSubmitEditProperty(param);
 		}
 	}
 };

Některé soubory nejsou zobrazeny, neboť je v těchto rozdílových datech změněno mnoho souborů