Browse Source

增加涂鸦绘制功能

不会爬树的猴 1 năm trước cách đây
mục cha
commit
517a89e3c6
33 tập tin đã thay đổi với 1216 bổ sung677 xóa
  1. BIN
      .DS_Store
  2. BIN
      node_modules/.DS_Store
  3. BIN
      node_modules/@arcgis/core/.DS_Store
  4. BIN
      node_modules/@arcgis/core/assets/.DS_Store
  5. BIN
      node_modules/@esri/calcite-components/dist/.DS_Store
  6. 127 0
      node_modules/copy-concurrently/README.md~
  7. BIN
      node_modules/element-plus/.DS_Store
  8. BIN
      node_modules/extglob/lib/.DS_Store
  9. 52 0
      node_modules/move-concurrently/README.md~
  10. BIN
      node_modules/mpd-parser/test/.DS_Store
  11. BIN
      node_modules/mpd-parser/test/manifests/.DS_Store
  12. BIN
      node_modules/querystring/.History.md.un~
  13. BIN
      node_modules/querystring/.Readme.md.un~
  14. BIN
      node_modules/querystring/.package.json.un~
  15. BIN
      node_modules/querystring/test/.index.js.un~
  16. BIN
      node_modules/vant/.DS_Store
  17. BIN
      node_modules/videojs-contrib-hls/node_modules/mux.js/dist/.DS_Store
  18. 3 0
      node_modules/videojs-contrib-hls/node_modules/pkcs7/lib/unpad.export.js~
  19. BIN
      node_modules/videojs-contrib-media-sources/node_modules/mux.js/dist/.DS_Store
  20. BIN
      node_modules/watchpack-chokidar2/node_modules/micromatch/lib/.DS_Store
  21. BIN
      node_modules/webpack/node_modules/micromatch/lib/.DS_Store
  22. BIN
      public/.DS_Store
  23. BIN
      public/resource/.DS_Store
  24. BIN
      src/.DS_Store
  25. BIN
      src/assets/.DS_Store
  26. 6 1
      src/assets/fonts/fonts.css
  27. BIN
      src/assets/fonts/iconfont.ttf
  28. BIN
      src/components/.DS_Store
  29. BIN
      src/components/CrMap/.DS_Store
  30. 25 16
      src/components/CrMap/CrMap.vue
  31. 230 6
      src/components/CrMap/DrawTools.js
  32. 186 88
      src/demo.html
  33. 587 566
      src/pages/tab-cmap.vue

BIN
.DS_Store


BIN
node_modules/.DS_Store


BIN
node_modules/@arcgis/core/.DS_Store


BIN
node_modules/@arcgis/core/assets/.DS_Store


BIN
node_modules/@esri/calcite-components/dist/.DS_Store


+ 127 - 0
node_modules/copy-concurrently/README.md~

@@ -0,0 +1,127 @@
+# copy-concurrently
+
+Copy files, directories and symlinks
+
+```
+const copy = require('copy-concurrently')
+copy('/path/to/thing', '/new/path/thing').then(() => {
+  // this is now copied
+}).catch(err => {
+  // oh noooo
+})
+```
+
+Copies files, directories and symlinks.  Ownership is maintained when
+running as root, permissions are always maintained.  On Windows, if symlinks
+are unavailable then junctions will be used.
+
+## PUBLIC INTERFACE
+
+### copy(from, to, [options]) → Promise
+
+Recursively copies `from` to `to` and resolves its promise when finished. 
+If `to` already exists then the promise will be rejected with an `EEXIST`
+error.
+
+Options are:
+
+* maxConcurrency – (Default: `1`) The maximum number of concurrent copies to do at once.
+* recurseWith - (Default: `copy.item`) The function to call on each file after recursing into a directory.
+* isWindows - (Default: `process.platform === 'win32'`) If true enables Windows symlink semantics. This requires
+  an extra `stat` to determine if the destination of a symlink is a file or directory. If symlinking a directory
+  fails then we'll try making a junction instead.
+
+Options can also include dependency injection:
+
+* Promise - (Default: `global.Promise`) The promise implementation to use, defaults to Node's.
+* fs - (Default: `require('fs')`) The filesystem module to use.  Can be used
+  to use `graceful-fs` or to inject a mock.
+* writeStreamAtomic - (Default: `require('fs-write-stream-atomic')`) The
+  implementation of `writeStreamAtomic` to use.  Used to inject a mock.
+* getuid - (Default: `process.getuid`) A function that returns the current UID. Used to inject a mock.
+
+## EXTENSION INTERFACE
+
+Ordinarily you'd only call `copy` above.  But it's possible to use it's
+component functions directly.  This is useful if, say, you're writing
+[move-concurently](https://npmjs.com/package/move-concurrently).
+
+### copy.file(from, to, options) → Promise
+
+Copies a ordinary file `from` to destination `to`.  Uses
+`fs-write-stream-atomic` to ensure that the file is entirely copied or not
+at all.
+
+Options are:
+
+* uid, gid - (Optional) If `getuid()` is `0` then this and gid will be used to
+  set the user and group of `to`.  If uid is present then gid must be too.
+* mode - (Optional) If set then `to` will have its perms set to `mode`.
+* fs - (Default: `require('fs')`) The filesystem module to use.  Can be used
+  to use `graceful-fs` or to inject a mock.
+* Promise - (Default: `global.Promise`) The promise implementation to use, defaults to Node's.
+* writeStreamAtomic - (Default `require('fs-write-stream-atomic')`) The
+  implementation of `writeStreamAtomic` to use.  Used to inject a mock.
+
+### copy.symlink(from, to, options) → Promise
+
+Copies a symlink `from` to destination `to`.  If on Windows then if
+symlinking fails, a junction will be used instead.
+
+Options are:
+
+* top - The top level the copy is being run from.  This is used to determine
+  if the symlink destination is within the set of files we're copying or
+  outside it.
+* fs - (Default: `require('fs')`) The filesystem module to use.  Can be used
+  to use `graceful-fs` or to inject a mock.
+* Promise - (Default: `global.Promise`) The promise implementation to use, defaults to Node's.
+* isWindows - (Default: `process.platform === 'win32'`) If true enables Windows symlink semantics. This requires
+  an extra `stat` to determine if the destination of a symlink is a file or directory. If symlinking a directory
+  fails then we'll try making a junction instead.
+
+### copy.recurse(from, to, options) → Promise
+
+Reads all of the files in directory `from` and adds them to the `queue`
+using `recurseWith` (by default `copy.item`).
+
+Options are:
+
+* queue - A [`run-queue`](https://npmjs.com/package/run-queue) object to add files found inside `from` to.
+* recurseWith - (Default: `copy.item`) The function to call on each file after recursing into a directory.
+* uid, gid - (Optional) If `getuid()` is `0` then this and gid will be used to
+  set the user and group of `to`.  If uid is present then gid must be too.
+* mode - (Optional) If set then `to` will have its perms set to `mode`.
+* fs - (Default: `require('fs')`) The filesystem module to use.  Can be used
+  to use `graceful-fs` or to inject a mock.
+* getuid - (Default: `process.getuid`) A function that returns the current UID. Used to inject a mock.
+
+### copy.item(from, to, options) → Promise
+
+Copies some kind of `from` to destination `to`.  This looks at the filetype
+and calls `copy.file`, `copy.symlink` or `copy.recurse` as appropriate.
+
+Symlink copies are queued with a priority such that they happen after all
+file and directory copies as you can't create a junction on windows to a
+file that doesn't exist yet.
+
+Options are:
+
+* top - The top level the copy is being run from.  This is used to determine
+  if the symlink destination is within the set of files we're copying or
+  outside it.
+* queue - The [`run-queue`](https://npmjs.com/package/run-queue) object to
+  pass to `copy.recurse` if `from` is a directory.
+* recurseWith - (Default: `copy.item`) The function to call on each file after recursing into a directory.
+* uid, gid - (Optional) If `getuid()` is `0` then this and gid will be used to
+  set the user and group of `to`.  If uid is present then gid must be too.
+* mode - (Optional) If set then `to` will have its perms set to `mode`.
+* fs - (Default: `require('fs')`) The filesystem module to use.  Can be used
+  to use `graceful-fs` or to inject a mock.
+* getuid - (Default: `process.getuid`) A function that returns the current UID. Used to inject a mock.
+* isWindows - (Default: `process.platform === 'win32'`) If true enables Windows symlink semantics. This requires
+  an extra `stat` to determine if the destination of a symlink is a file or directory. If symlinking a directory
+  fails then we'll try making a junction instead.
+* Promise - (Default: `global.Promise`) The promise implementation to use, defaults to Node's.
+* writeStreamAtomic - (Default `require('fs-write-stream-atomic')`) The
+  implementation of `writeStreamAtomic` to use.  Used to inject a mock.

BIN
node_modules/element-plus/.DS_Store


BIN
node_modules/extglob/lib/.DS_Store


+ 52 - 0
node_modules/move-concurrently/README.md~

@@ -0,0 +1,52 @@
+# move-concurrently
+
+Move files and directories.
+
+```
+const move = require('move-concurrently')
+move('/path/to/thing', '/new/path/thing'), err => {
+  if (err) throw err
+  // thing is now moved!
+})
+```
+
+Uses `rename` to move things as fast as possible.
+
+If you `move` across devices or on filesystems that don't support renaming
+large directories.  That is, situations that result in `rename` returning
+the `EXDEV` error, then `move` will fallback to copy + delete.
+
+When recursively copying directories it will first try to rename the
+contents before falling back to copying.  While this will be slightly slower
+in true cross-device scenarios, it is MUCH faster in cases where the
+filesystem can't handle directory renames.
+
+When copying ownership is maintained when running as root.  Permissions are
+always maintained.  On Windows, if symlinks are unavailable then junctions
+will be used.
+
+## INTERFACE
+
+### move(from, to, options) → Promise
+
+Recursively moves `from` to `to` and resolves its promise when finished.
+If `to` already exists then the promise will be rejected with an `EEXIST`
+error.
+
+Starts by trying to rename `from` to `to`.
+
+Options are:
+
+* maxConcurrency – (Default: `1`) The maximum number of concurrent copies to do at once.
+* isWindows - (Default: `process.platform === 'win32'`) If true enables Windows symlink semantics. This requires
+  an extra `stat` to determine if the destination of a symlink is a file or directory. If symlinking a directory
+  fails then we'll try making a junction instead.
+
+Options can also include dependency injection:
+
+* Promise - (Default: `global.Promise`) The promise implementation to use, defaults to Node's.
+* fs - (Default: `require('fs')`) The filesystem module to use.  Can be used
+  to use `graceful-fs` or to inject a mock.
+* writeStreamAtomic - (Default: `require('fs-write-stream-atomic')`) The
+  implementation of `writeStreamAtomic` to use.  Used to inject a mock.
+* getuid - (Default: `process.getuid`) A function that returns the current UID. Used to inject a mock.

BIN
node_modules/mpd-parser/test/.DS_Store


BIN
node_modules/mpd-parser/test/manifests/.DS_Store


BIN
node_modules/querystring/.History.md.un~


BIN
node_modules/querystring/.Readme.md.un~


BIN
node_modules/querystring/.package.json.un~


BIN
node_modules/querystring/test/.index.js.un~


BIN
node_modules/vant/.DS_Store


BIN
node_modules/videojs-contrib-hls/node_modules/mux.js/dist/.DS_Store


+ 3 - 0
node_modules/videojs-contrib-hls/node_modules/pkcs7/lib/unpad.export.js~

@@ -0,0 +1,3 @@
+var pkcs7 = window.pkcs7 || {};
+
+pkcs7.unpad = require('pkcs7').unpad;

BIN
node_modules/videojs-contrib-media-sources/node_modules/mux.js/dist/.DS_Store


BIN
node_modules/watchpack-chokidar2/node_modules/micromatch/lib/.DS_Store


BIN
node_modules/webpack/node_modules/micromatch/lib/.DS_Store


BIN
public/.DS_Store


BIN
public/resource/.DS_Store


BIN
src/.DS_Store


BIN
src/assets/.DS_Store


+ 6 - 1
src/assets/fonts/fonts.css

@@ -197,4 +197,9 @@
 /* 标绘工具 */
 .app-icon-tools-draw::before {
 	content: '\e702';
-}
+}
+
+/* 涂鸦 */
+.app-icon-tools-doodle::before {
+	content: '\e713';
+}

BIN
src/assets/fonts/iconfont.ttf


BIN
src/components/.DS_Store


BIN
src/components/CrMap/.DS_Store


+ 25 - 16
src/components/CrMap/CrMap.vue

@@ -322,6 +322,15 @@
 		},
 
 		/**
+		 * 绘制涂鸦
+		 */
+		onMouseDrawDoodle: function() {
+			proxy.drawTools.draw(DrawTools.DrawType.Doodle, {
+				isEdit: true
+			});
+		},
+
+		/**
 		 * 更新墙属性
 		 * @param {JSON} params 参数配置项
 		 */
@@ -429,19 +438,19 @@
 		// });
 
 		/* 添加实景地图 */
-		proxy.CMapApi.addLayer({
-			layId: 'yt3d',
-			layName: '烟台实景',
-			layType: CrMap.LayerType.tilesetsLayer,
-			isShow: true,
-			config: {
-				url: ['http://218.59.194.82:13080/crdata/sdly/crtiles/tileset.json',
-					'http://218.59.194.82:13080/crdata/sdyt/crtile/zxc/1tiles/tileset1.json'
-				]
-			}
-		});
+		// proxy.CMapApi.addLayer({
+		// 	layId: 'yt3d',
+		// 	layName: '烟台实景',
+		// 	layType: CrMap.LayerType.tilesetsLayer,
+		// 	isShow: true,
+		// 	config: {
+		// 		url: ['http://218.59.194.82:13080/crdata/sdly/crtiles/tileset.json',
+		// 			'http://218.59.194.82:13080/crdata/sdyt/crtile/zxc/1tiles/tileset1.json'
+		// 		]
+		// 	}
+		// });
 
-		/* 添加实景地图 */
+		/* 添加牟平实景地图 */
 		proxy.CMapApi.addLayer({
 			layId: 'qp3d01',
 			layName: '牟平三维',
@@ -567,10 +576,10 @@
 			// strLat: 35.14124100849915,
 			// endLng: 118.22865486061352,
 			// endLat: 35.14589687229257,
-			strLng: 118.05,
-			strLat: 34.953,
-			endLng: 118.53,
-			endLat: 35.434,
+			strLng: 121.561,
+			strLat: 37.400,
+			endLng: 121.566,
+			endLat: 37.413,
 			success: function() {
 				/* 设置地形*/
 				_self.CMapApi.setTerrain({

+ 230 - 6
src/components/CrMap/DrawTools.js

@@ -907,7 +907,7 @@ class DrawTools {
 			outlineColor: outlineColor,
 			outlineWidth: outlineWidth,
 		}
-		/* 返回材��������������������� */
+		/* 返回材 */
 		return colorMaterial;
 	}
 
@@ -1167,6 +1167,38 @@ Object.assign(DrawTools.prototype, {
 	},
 
 	/**
+	 * 创建涂鸦线
+	 */
+	_createDoodlePolyline: function() {
+		let _self = this;
+		/* 创建空间线 */
+		let entityPolyline = new Cesium.Entity({
+			name: _self._sketchEntityName,
+			polyline: {
+				show: true,
+				positions: new Cesium.CallbackProperty(function() {
+					return _self._sketchTempPoints;
+				}, false),
+				material: _self._doodlePolylineColor === undefined ? Cesium.Color.YELLOW : Cesium.Color
+					.fromCssColorString(_self._doodlePolylineColor),
+				width: 3.0,
+				clampToGround: _self._doodlePolylineIsFitModel === undefined ? false : _self
+					._doodlePolylineIsFitModel, //贴地模式选择
+			}
+		})
+		/* 渲染空间线 */
+		this._drawEntity = this._entities.add(entityPolyline);
+	},
+
+	/**
+	 * 更新涂鸦线
+	 */
+	_updateDoodlePolyline() {
+		/* 更新数据 */
+		this._drawEntity.polyline.positions = this._sketchTempPoints;
+	},
+
+	/**
 	 * 更新贴地线
 	 * @ignore 生成方法时不对外公开
 	 * @param {Boolean} isEdit [是否可编辑] 可选
@@ -2305,6 +2337,75 @@ Object.assign(DrawTools.prototype, {
 	},
 
 	/**
+	 * 绘制涂鸦
+	 * @param {Object} handler
+	 * @param {Object} options
+	 */
+	_sketchDrawDoodle(handler, options) {
+		let _self = this;
+		/* 注册鼠标左键按下事件 */
+		_self._registerLeftDownEvent(handler, function(event) {
+			_self._doodleState = 1; /* 表示涂鸦开始 */
+			/* 锁定操作 */
+			_self._viewer.scene.screenSpaceCameraController.enableInputs = false;
+			/* 识别屏幕位置 */
+			let loc = _self._transfromFromScreenPoint(event.position);
+			_self._sketchTempPoints.push(loc.sLocation);
+			/* 创建涂鸦线 */
+			_self._createDoodlePolyline();
+		});
+		/* 注册鼠标左键抬起事件 */
+		_self._registerLeftUpEvent(handler, function(event) {
+			if (_self._doodleState !== undefined && _self._doodleState === 1) {
+				_self._doodleState = 0;
+				/* 更新涂鸦线 */
+				_self._updateDoodlePolyline();
+				/* 清理本地绘制数据 */
+				_self._sketchTempPoints = [];
+			}
+		});
+		/* 注册鼠标左键移动事件 */
+		_self._registerMouseMoveEvent(handler, function(event) {
+			if (_self._doodleState !== undefined && _self._doodleState === 1) {
+				/* 识别屏幕位置 */
+				let loc = _self._transfromFromScreenPoint(event.endPosition);
+				_self._sketchTempPoints.push(loc.sLocation);
+				/* 标签提示 */
+				_self._updateTooltip(undefined, event.endPosition);
+			}
+		});
+		/* 注册右键事件 */
+		_self._registerRightClickEvent(handler, function(event) {
+			let menu = [{
+				name: '贴合模式',
+				model: '0',
+			}, {
+				name: '悬空模式',
+				model: '1',
+			}, {
+				name: '结束绘制',
+				model: '2',
+			}]
+			_self._showRightMouseMenu(menu, event.position, function(model, value) {
+				if (model === 'fun' && value === '0') {
+					_self._doodlePolylineIsFitModel = true;
+				} else if (model === 'fun' && value === '1') {
+					_self._doodlePolylineIsFitModel = false;
+				} else if (model === 'fun' && value === '2') {
+					/* 清理涂鸦状态 */
+					_self._doodleState = 0;
+					/* 干掉事件句柄 释放资源*/
+					_self._clearEvent(handler);
+					/* 解除锁定 */
+					_self._viewer.scene.screenSpaceCameraController.enableInputs = true;
+				} else if (model === 'color') {
+					_self._doodlePolylineColor = value;
+				}
+			})
+		})
+	},
+
+	/**
 	 * 绘制贴地面工具
 	 * @ignore 生成方法时不对外公开
 	 * @param {Object} handler 事件句柄
@@ -2695,7 +2796,11 @@ Object.assign(DrawTools.prototype, {
 		if (this._isRuntimeApp()) {
 			this._showTooltipMessage("单击绘制");
 		} else {
-			this._beginTooltip('左键单击绘制', undefined);
+			if (type === DrawTools.DrawType.Doodle) {
+				this._beginTooltip('鼠标按下绘制<br>鼠标抬起结束本次绘制<br>右键设置', undefined);
+			} else {
+				this._beginTooltip('左键单击绘制', undefined);
+			}
 		}
 		this._drawType = type;
 		/* 分类型注册事件 */
@@ -2727,17 +2832,17 @@ Object.assign(DrawTools.prototype, {
 				options.polygonType = DrawTools.PolygonType.NormalPolygon;
 				_self._sketchDrawPolygon(_self._drawEventHandler, options);
 				break;
-			case DrawTools.DrawType.SpatialLine: //绘制空���线
+			case DrawTools.DrawType.SpatialLine: //绘制空线
 				_self._sketchDrawSpatialPolyline(_self._drawEventHandler, options);
 				break;
-			case DrawTools.DrawType.Circle: //绘�����贴�����
+			case DrawTools.DrawType.Circle: //绘制贴地
 				options.circleType = DrawTools.CircleType.ColorCircle;
 				_self._sketchDrawCircle(_self._drawEventHandler, options);
 				break;
 			case DrawTools.DrawType.Rectangle: //绘制矩形
 				_self._sketchDrawRectangle(_self._drawEventHandler, options);
 				break;
-			case DrawTools.DrawType.NormalWall: //������普通墙
+			case DrawTools.DrawType.NormalWall: //绘制普通墙
 				options.wallType = DrawTools.WallType.ColorWall;
 				_self._sketchDrawWall(_self._drawEventHandler, options);
 				break;
@@ -2749,7 +2854,7 @@ Object.assign(DrawTools.prototype, {
 				options.wallType = DrawTools.WallType.TextWall;
 				_self._sketchDrawWall(_self._drawEventHandler, options);
 				break;
-			case DrawTools.DrawType.DynamicCircle: //���制扩散圆
+			case DrawTools.DrawType.DynamicCircle: //制扩散圆
 				options.circleType = DrawTools.CircleType.DynamicCircle;
 				_self._sketchDrawCircle(_self._drawEventHandler, options);
 				break;
@@ -2763,6 +2868,9 @@ Object.assign(DrawTools.prototype, {
 			case DrawTools.DrawType.OdLine:
 				_self._sketchDrawOdline(_self._drawEventHandler, options);
 				break;
+			case DrawTools.DrawType.Doodle:
+				_self._sketchDrawDoodle(_self._drawEventHandler, options);
+				break;
 		}
 	},
 
@@ -3011,6 +3119,121 @@ Object.assign(DrawTools.prototype, {
 		setTimeout(function() {
 			msgMainDom.style.transform = 'translateY(50px)';
 		}, 100)
+	},
+
+	/**
+	 * 添加右键菜单
+	 * @param {Array(JSON)} menuJSON 菜单数据
+	 * @param {JSON} 鼠标位置
+	 * @param {Function} callback(model,value) 回调
+	 */
+	_showRightMouseMenu(menuJSON, mousePosition, callback) {
+		let menuObj = document.getElementById("divMenu");
+		if (menuObj === null) {
+			menuObj = document.createElement('div');
+			let divStyle = "height: auto;";
+			divStyle += "position: absolute;";
+			divStyle += "width:110px;";
+			divStyle += "background-color: rgba(0, 0, 0, 0.65);";
+			divStyle += "border-radius: 5px;";
+			divStyle += "color: rgb(255, 255, 0);";
+			divStyle += "font-size: 13px;";
+			divStyle += "font-family: 'Alimama_ShuHeiTi_Bold';";
+			divStyle += "padding: 8px 0px;";
+			divStyle += "border:solid 1px rgb(255,0,0);";
+			divStyle += "display: flex;";
+			divStyle += "flex-direction: column;";
+			menuObj.setAttribute('style', divStyle);
+			document.body.appendChild(menuObj);
+			//菜单正常样式
+			let subDivStyle = "height: 34px;";
+			subDivStyle += "display: flex;";
+			subDivStyle += "align-items: center;";
+			subDivStyle += "justify-content: center;";
+			//菜单滑入滑出样式
+			let hoverStyle = subDivStyle;
+			hoverStyle += "font-size: 14px;";
+			hoverStyle += "cursor: pointer;";
+			hoverStyle += "font-weight: bold;";
+			hoverStyle += "color: rgb(255, 255, 255);";
+			hoverStyle += "background-color: rgb(255, 0, 0);";
+			for (let menu of menuJSON) {
+				let menuSub = document.createElement('div');
+				menuSub.innerHTML = menu.name;
+				menuSub.setAttribute('style', subDivStyle);
+				//追加移入事件
+				menuSub.onmouseenter = function() {
+					this.setAttribute('style', hoverStyle);
+				};
+				//追加移除事件
+				menuSub.onmouseleave = function() {
+					this.setAttribute('style', subDivStyle);
+				};
+				//追加点击事件
+				menuSub.onclick = function() {
+					menuObj.style.display = 'none';
+					if (callback !== undefined) callback('fun', menu.model);
+				}
+				menuObj.appendChild(menuSub);
+			}
+			//追加颜色选择器
+			let menuColorJSON = [{
+				name: 'rgb(255,0,0)'
+			}, {
+				name: 'rgb(255,255,0)'
+			}, {
+				name: 'rgb(0,255,0)'
+			}, {
+				name: 'rgb(0,0,255)'
+			}]
+			//颜色子控件样式
+			let colorDivStyle = "flex: 1;";
+			colorDivStyle += "margin-right: 3px;";
+			colorDivStyle += "margin-left: 3px;";
+			colorDivStyle += "border-radius: 5px;";
+			//颜色子控件滑入滑出样式
+			let colorHoverStyle = colorDivStyle;
+			colorHoverStyle += "border: solid 1px rgb(255, 255, 255);";
+			colorHoverStyle += "cursor: pointer;";
+			//颜色子控件容器样式
+			let colorDomStyle = "border-top: solid 1px rgba(255, 255, 255, 0.85);";
+			colorDomStyle += "height: 22px;";
+			colorDomStyle += "display: flex;";
+			colorDomStyle += "flex-direction: row;";
+			colorDomStyle += "margin-top: 8px;";
+			colorDomStyle += "padding-top: 8px;";
+			//创建控件
+			let colorDivDom = document.createElement('div');
+			colorDivDom.setAttribute('style', colorDomStyle);
+			menuObj.appendChild(colorDivDom);
+			for (let menuColor of menuColorJSON) {
+				let colorDivSub = document.createElement('div');
+				colorDivSub.setAttribute('style', colorDivStyle);
+				colorDivSub.style.backgroundColor = menuColor.name;
+				colorDivDom.appendChild(colorDivSub);
+				colorDivSub.onmouseenter = function() {
+					this.setAttribute('style', colorHoverStyle);
+					this.style.backgroundColor = menuColor.name;
+				}
+				colorDivSub.onmouseleave = function() {
+					this.setAttribute('style', colorDivStyle);
+					this.style.backgroundColor = menuColor.name;
+				}
+				colorDivSub.onclick = function() {
+					menuObj.style.display = 'none';
+					if (callback !== undefined) callback('color', menuColor.name);
+				}
+			}
+		} else {
+			menuObj.style.display = 'flex';
+		}
+		if (mousePosition !== undefined) {
+			menuObj.style.display = 'flex';
+			menuObj.style.left = (mousePosition.x + 10) + 'px';
+			menuObj.style.top = (mousePosition.y - menuObj.offsetHeight / 2) + 'px';
+		} else {
+			menuObj.style.display = 'none';
+		}
 	}
 })
 
@@ -5411,6 +5634,7 @@ DrawTools.DrawType = Object.freeze({
 	House: 'house', //房屋
 	TextWall: 'text', //文字
 	VideoWall: 'videoWall', //视频墙
+	Doodle: 'doodle', //涂鸦
 })
 
 

+ 186 - 88
src/demo.html

@@ -3,105 +3,203 @@
 	<head>
 		<meta charset="utf-8">
 		<title>DEMO页面</title>
+		<style>
+			.cr-menu {
+				background-color: rgba(0, 0, 0, 0.65);
+				width: 110px;
+				color: rgb(255, 255, 0);
+				padding: 8px 0px;
+				font-size: 13px;
+				display: flex;
+				flex-direction: column;
+			}
+
+			.cr-menu-normal {
+				height: 34px;
+				display: flex;
+				align-items: center;
+				justify-content: center;
+			}
+
+			.cr-menu-normal:hover {
+				font-size: 14px;
+				cursor: pointer;
+				font-weight: bold;
+				color: rgb(255, 255, 255);
+				background-color: rgb(255, 0, 0);
+
+			}
+
+			.cr-menu-color {
+				border-top: solid 1px rgba(255, 255, 255, 0.85);
+				height: 22px;
+				display: flex;
+				flex-direction: row;
+				margin-top: 8px;
+				padding-top: 8px;
+			}
+
+			.cr-menu-color-sub {
+				flex: 1;
+				margin-right: 3px;
+				margin-left: 3px;
+				border-radius: 5px;
+			}
+
+			.cr-menu-color-sub:hover {
+				border: solid 1px rgb(255, 255, 255);
+				cursor: pointer;
+			}
+		</style>
 	</head>
 	<body>
-		<video id="rtc_media_player" controls autoplay></video>
+		<div class="cr-menu">
+			<div class="cr-menu-normal">贴合模式</div>
+			<div class="cr-menu-normal">悬空模式</div>
+			<div class="cr-menu-normal">结束绘制</div>
+			<div class="cr-menu-color">
+				<div class="cr-menu-color-sub" style="background-color: rgb(255, 0, 0);"></div>
+				<div class="cr-menu-color-sub" style="background-color: rgb(255, 255, 0);"></div>
+				<div class="cr-menu-color-sub" style="background-color: rgb(0, 255, 0);"></div>
+				<div class="cr-menu-color-sub" style="background-color: rgb(0, 0, 255);"></div>
+			</div>
+		</div>
 	</body>
 </html>
 <script src="../public/js/srs.sdk.js"></script>
 <!-- 引入地理工具箱 -->
 <script src="https://unpkg.com/@turf/turf/turf.min.js"></script>
 <script type="text/javascript">
-	function playWebRTC() {
-		let videoElement = document.getElementById('rtc_media_player');
-		var sdk = null;
-		if (sdk) {
-			sdk.close();
-		}
-		sdk = new SrsRtcPlayerAsync();
-		videoElement.srcObject = sdk.stream;
-		sdk.play('webrtc://10.88.88.172/live/stream/videoName.flv').then(function(session) {
-			console.log("SessionId=" + session.sessionid);
-		}).catch(function(reason) {
-			console.log("错误=" + reason);
-		})
-	}
-
-	var pt = turf.point([118.675728, 35.075311]);
-	var converted = turf.toMercator(pt);
-	console.log(converted.geometry.coordinates);
-
-	// let mmm = calculateCoordinate(1920, 1080, 2.883, 4.9, 0, 90, 200);
-	// let mmm = calculateCoordinate(8192, 5460, 4.4, 35, 0, 90, 400);
-	let mmm = calculateRectangle(118.675728, 35.075311, 8192, 5460, 4.4, 35, 0, 90, 400);
-	console.log(mmm);
-
-
-	function calculateRectangle(longitude, latitude, width, height, pix, foucsLength, o, k, airHeight) {
-		/* 将经纬度转换为Web墨卡托 */
-		let pt = turf.point([longitude, latitude]);
-		let webPt = turf.toMercator(pt).geometry.coordinates;
-		/* 计算四点坐标 */
-		let res = calculateCoordinate(width, height, pix, foucsLength, o, k, airHeight);
-		let rectangle = [];
-		for (let idx in res) {
-			let tempWebPt = turf.point([res[idx][0] + webPt[0], res[idx][1] + webPt[1]]);
-			let tempG84Pt = turf.toWgs84(tempWebPt);
-			rectangle.push(tempG84Pt.geometry.coordinates)
-		}
-		/* 返回 */
-		return {
-			center: [longitude, latitude],
-			height: airHeight,
-			rectangle: rectangle
-		}
-	}
+	let menuJSON = [{
+		name: '贴合模式',
+		model: '0',
+	}, {
+		name: '悬空模式',
+		model: '1',
+	}, {
+		name: '结束绘制',
+		model: '2',
+	}]
 
+	_showRightMouseMenu(menuJSON, {
+		x: 100,
+		y: 300,
+	}, function(model, value) {
+		console.log(model, value);
+	});
 
 	/**
-	 * 计算坐标集合
-	 * @param {Number} width 图像宽度
-	 * @param {Number} height 图像高度
-	 * @param {Number} pix 像元大小 单位微米
-	 * @param {Number} foucsLength 焦距 单位毫米
-	 * @param {Number} o 俯仰角(相机)度
-	 * @param {Number} k 旋偏角(相机)度
-	 * @param {Number} airHeight 飞行高度
+	 * 添加右键菜单
+	 * @param {Array(JSON)} menuJSON 菜单数据
+	 * @param {JSON} 鼠标位置
+	 * @param {Function} callback(model,value) 回调
 	 */
-	function calculateCoordinate(width, height, pix, foucsLength, o, k, airHeight) {
-		let arcO = o * (Math.PI / 180);
-		let arcK = k * (Math.PI / 180);
-		let sinO = Math.sin(arcO);
-		let cosO = Math.cos(arcO);
-		let sinK = Math.sin(arcK);
-		let cosK = Math.cos(arcK);
-		let fp = foucsLength / pix * 1000;
-		/* 计算第一点 */
-		let ax = (airHeight * (height * cosO * sinK - width * cosK + 2 * fp * sinK * sinO)) / (2 * fp * cosO - height *
-			sinO);
-		let ay = (airHeight * (width * sinK + height * cosK * cosO + 2 * fp * cosK * sinO)) / (2 * fp * cosO - height *
-			sinO);
-		/* 计算第二点 */
-		let bx = (airHeight * (width * cosK + height * cosO * sinK + 2 * fp * sinK * sinO)) / (2 * fp * cosO - height *
-			sinO);
-		let by = (airHeight * (height * cosK * cosO - width * sinK + 2 * fp * cosK * sinO)) / (2 * fp * cosO - height *
-			sinO);
-		/* 计算第三点 */
-		let cx = (airHeight * (width * cosK - height * cosO * sinK + 2 * fp * sinK * sinO)) / (2 * fp * cosO + height *
-			sinO);
-		let cy = -1 * (airHeight * (width * sinK + height * cosK * cosO - 2 * fp * cosK * sinO)) / (2 * fp * cosO + height *
-			sinO);
-		/* 计算第四点 */
-		let dx = -1 * (airHeight * (width * cosK + height * cosO * sinK - 2 * fp * sinK * sinO)) / (2 * fp * cosO + height *
-			sinO);
-		let dy = (airHeight * (width * sinK - height * cosK * cosO + 2 * fp * cosK * sinO)) / (2 * fp * cosO + height *
-			sinO);
-		/* 返回计算结果 */
-		return [
-			[ax, ay],
-			[bx, by],
-			[cx, cy],
-			[dx, dy]
-		];
+	function _showRightMouseMenu(menuJSON, mousePosition, callback) {
+		let menuObj = document.getElementById("divMenu");
+		if (menuObj === null) {
+			menuObj = document.createElement('div');
+			let divStyle = "height: auto;";
+			divStyle += "position: absolute;";
+			divStyle += "width:110px;";
+			divStyle += "background-color: rgba(0, 0, 0, 0.65);";
+			divStyle += "border-radius: 5px;";
+			divStyle += "color: rgb(255, 255, 0);";
+			divStyle += "font-size: 13px;";
+			divStyle += "font-family: 'Alimama_ShuHeiTi_Bold';";
+			divStyle += "padding: 8px 0px;";
+			divStyle += "border:solid 1px rgb(255,0,0);";
+			divStyle += "display: flex;";
+			divStyle += "flex-direction: column;";
+			menuObj.setAttribute('style', divStyle);
+			document.body.appendChild(menuObj);
+			//菜单正常样式
+			let subDivStyle = "height: 34px;";
+			subDivStyle += "display: flex;";
+			subDivStyle += "align-items: center;";
+			subDivStyle += "justify-content: center;";
+			//菜单滑入滑出样式
+			let hoverStyle = subDivStyle;
+			hoverStyle += "font-size: 14px;";
+			hoverStyle += "cursor: pointer;";
+			hoverStyle += "font-weight: bold;";
+			hoverStyle += "color: rgb(255, 255, 255);";
+			hoverStyle += "background-color: rgb(255, 0, 0);";
+			for (let menu of menuJSON) {
+				let menuSub = document.createElement('div');
+				menuSub.innerHTML = menu.name;
+				menuSub.setAttribute('style', subDivStyle);
+				//追加移入事件
+				menuSub.onmouseenter = function() {
+					this.setAttribute('style', hoverStyle);
+				};
+				//追加移除事件
+				menuSub.onmouseleave = function() {
+					this.setAttribute('style', subDivStyle);
+				};
+				//追加点击事件
+				menuSub.onclick = function() {
+					menuObj.style.display = 'none';
+					if (callback !== undefined) callback('fun', menu.model);
+				}
+				menuObj.appendChild(menuSub);
+			}
+			//追加颜色选择器
+			let menuColorJSON = [{
+				name: 'rgb(255,0,0)'
+			}, {
+				name: 'rgb(255,255,0)'
+			}, {
+				name: 'rgb(0,255,0)'
+			}, {
+				name: 'rgb(0,0,255)'
+			}]
+			//颜色子控件样式
+			let colorDivStyle = "flex: 1;";
+			colorDivStyle += "margin-right: 3px;";
+			colorDivStyle += "margin-left: 3px;";
+			colorDivStyle += "border-radius: 5px;";
+			//颜色子控件滑入滑出样式
+			let colorHoverStyle = colorDivStyle;
+			colorHoverStyle += "border: solid 1px rgb(255, 255, 255);";
+			colorHoverStyle += "cursor: pointer;";
+			//颜色子控件容器样式
+			let colorDomStyle = "border-top: solid 1px rgba(255, 255, 255, 0.85);";
+			colorDomStyle += "height: 22px;";
+			colorDomStyle += "display: flex;";
+			colorDomStyle += "flex-direction: row;";
+			colorDomStyle += "margin-top: 8px;";
+			colorDomStyle += "padding-top: 8px;";
+			//创建控件
+			let colorDivDom = document.createElement('div');
+			colorDivDom.setAttribute('style', colorDomStyle);
+			menuObj.appendChild(colorDivDom);
+			for (let menuColor of menuColorJSON) {
+				let colorDivSub = document.createElement('div');
+				colorDivSub.setAttribute('style', colorDivStyle);
+				colorDivSub.style.backgroundColor = menuColor.name;
+				colorDivDom.appendChild(colorDivSub);
+				colorDivSub.onmouseenter = function() {
+					this.setAttribute('style', colorHoverStyle);
+					this.style.backgroundColor = menuColor.name;
+				}
+				colorDivSub.onmouseleave = function() {
+					this.setAttribute('style', colorDivStyle);
+					this.style.backgroundColor = menuColor.name;
+				}
+				colorDivSub.onclick = function() {
+					menuObj.style.display = 'none';
+					if (callback !== undefined) callback('color', menuColor.name);
+				}
+			}
+		} else {
+			menuObj.style.display = 'flex';
+		}
+		if (mousePosition !== undefined) {
+			menuObj.style.display = 'flex';
+			menuObj.style.left = (mousePosition.x + 10) + 'px';
+			menuObj.style.top = (mousePosition.y - menuObj.offsetHeight / 2) + 'px';
+		} else {
+			menuObj.style.display = 'none';
+		}
 	}
 </script>

+ 587 - 566
src/pages/tab-cmap.vue

@@ -1,566 +1,587 @@
-<template>
-	<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>
-	<view class="cr-tools-right">
-		<ToolButton v-for="(item, index) in rightTools" :id="item.id" :title="item.title" :describe="item.describe" :icon="item.icon" @onclick="onToolsClick" />
-	</view>
-	<jtDialog class="jt-tools-dialog" :showDialog="showDialog" title="动态标绘" height="calc(100% - 50px)" width="300px" top="0px" @closeJTDialog="closeDialog">
-		<el-row :gutter="20">
-			<el-col :span="8" v-for="(item, index) in dynamicDrawTools" @click="onDrawToolsClick(item)">
-				<el-avatar shape="circle" :size="50" style="background-color: bisque;"><i :class="item.iconName" /></el-avatar>
-				<cite>{{ item.title }}</cite>
-			</el-col>
-		</el-row>
-	</jtDialog>
-
-	<!-- 墙的编辑框 -->
-	<dialogEditProperty ref="dialogEdit" :params="editParams" @submit="submit" @remove="remove" v-model:showDialog="showEditDialog"></dialogEditProperty>
-</template>
-<script setup>
-import { Dialog } from 'vant';
-/* 引入弹出对话框 */
-import jtDialog from '../components/jt-dialog/dialog.vue';
-/* 引入墙的编辑对话框 */
-import dialogEditProperty from '../components/jt-dialog/dialogEditProperty.vue';
-</script>
-<script>
-/* 引入三维地图控件 */
-import CrMap from '../components/CrMap/CrMap.vue';
-import { DrawTools } from '../components/CrMap/DrawTools.js';
-import { ref } from 'vue';
-/* 引入工具按钮 */
-import ToolButtom from '../components/ToolButton/ToolButton.vue';
-export default {
-	components: {
-		CrMap
-	},
-	/* 返回数据 */
-	data() {
-		return {
-			leftTools: [],
-			rightTools: [],
-			showOverlay: false,
-			poputNavTitle: '物体样式调整',
-			color: {
-				red: 0,
-				green: 100,
-				blue: 255,
-				alpha: 6
-			},
-			height: 120,
-			dialogVisible: false,
-			showDialog: false,
-			editParams: undefined,
-			showEditDialog: false,
-			dynamicDrawTools: []
-		};
-	},
-	/* 创建 */
-	created() {
-		let _self = this;
-		/* 工具标题初始化 */
-		this.leftTools.push({
-			title: '长度量测',
-			describe: '在地图上点击需要测量对象的特征位置,即可实时计算长度并展示',
-			icon: 'app-icon-map-measurelength',
-			id: 'length'
-		});
-		this.leftTools.push({
-			title: '面积量测',
-			describe: '在地图上点击需要测量的对象特征位置,即可实时计算面积并展示',
-			icon: 'app-icon-map-measurearea',
-			id: 'area'
-		});
-		this.leftTools.push({
-			title: '高度测量',
-			describe: '在地图上点击需要测量的对象特征位置,即可实时计算高度并展示',
-			icon: 'app-icon-map-measureheight',
-			id: 'height'
-		});
-		this.leftTools.push({
-			title: '空间测量',
-			describe: '在地图上点击需要测量的对象特征位置,即可实时计算空间距离并展示',
-			icon: 'app-icon-map-measurespace',
-			id: 'space'
-		});
-		this.leftTools.push({
-			title: '三角测量',
-			describe: '在地图上点击需要测量对象的特征位置,即可实时计算长度并展示',
-			icon: 'app-icon-map-measuretriangle',
-			id: 'triangle'
-		});
-		this.leftTools.push({
-			title: '点击查询',
-			describe: '点击后,在需要查询的位置单击,即可查询该位置的全部可见图层数据',
-			icon: 'app-icon-map-query-point',
-			id: 'queryByPoint'
-		});
-		this.leftTools.push({
-			title: '多点查询',
-			describe: '点击后,在需要查询的位置单击,即可查询该位置的全部可见图层数据',
-			icon: 'app-icon-map-query-multiple-point',
-			id: 'queryByMultiplePoint'
-		});
-		this.leftTools.push({
-			title: '线查询',
-			describe: '点击后,在需要查询的位置单击,即可查询该位置的全部可见图层数据',
-			icon: 'app-icon-map-query-point',
-			id: 'queryByLine'
-		});
-		this.leftTools.push({
-			title: '圆查询',
-			describe: '点击后,在需要查询的位置单击,即可查询该位置的全部可见图层数据',
-			icon: 'app-icon-map-query-point',
-			id: 'queryByCircle'
-		});
-		this.leftTools.push({
-			title: '矩形查询',
-			describe: '点击后,在需要查询的位置单击,即可查询该位置的全部可见图层数据',
-			icon: 'app-icon-map-query-point',
-			id: 'queryByRectangle'
-		});
-		this.leftTools.push({
-			title: '区域查询',
-			describe: '点击后,在地图上绘制查询区域,单击开始查询,即可查询该区域内的全部可见图层数据',
-			icon: 'app-icon-map-query-polygon',
-			id: 'queryByPolygon'
-		});
-		this.leftTools.push({
-			title: '清理绘制',
-			describe: '在地图上单击绘制底部,右键结束绘制拉伸',
-			icon: 'app-icon-map-clean',
-			id: 'toolsClear'
-		});
-
-		this.rightTools.push({
-			title: '图层管理',
-			describe: '点击即可打开图层控制窗口,进行图层及标注的显示/隐藏',
-			icon: 'app-icon-map-layer',
-			id: 'layerControl'
-		});
-		this.rightTools.push({
-			title: '动态标绘',
-			describe: '点击即可打开图层控制窗口,进行图层及标注的显示/隐藏',
-			icon: 'app-icon-tools-draw',
-			id: 'dynamicDraw'
-		});
-		this.rightTools.push({
-			title: '重置地图',
-			describe: '点击即可重置地图范围为初始显示范围',
-			icon: 'app-icon-map-initlocation',
-			id: 'initMapExtent'
-		});
-		this.rightTools.push({
-			title: '坐标查询',
-			describe: '在地图上需要查询坐标的位置上点击,即可查询该位置的地理坐标',
-			icon: 'app-icon-map-querycoord',
-			id: 'coordQuery'
-		});
-		this.rightTools.push({
-			title: '坐标定位',
-			describe: '点击后,弹出坐标输入框,输入正确的位置坐标后点击定位,即可在地图上展示坐标位置',
-			icon: 'app-icon-map-inputcoord-location',
-			id: 'inputLocation'
-		});
-		this.rightTools.push({
-			title: '相机视角',
-			describe: '点击后,弹出坐标输入框,输入正确的位置坐标后点击定位,即可在地图上展示坐标位置',
-			icon: 'app-icon-map-camera-view',
-			id: 'cameraView'
-		});
-		this.rightTools.push({
-			title: '物体拾取',
-			describe: '点击后,在地图上的实体上单击,即可拾取该实体',
-			icon: 'app-icon-map-pick',
-			id: 'pick'
-		});
-		this.rightTools.push({
-			title: '清扫工具',
-			describe: '清除地图上的各类绘制内容',
-			icon: 'app-icon-map-clean',
-			id: 'clear'
-		});
-		/* 动态标绘工具 */
-		this.dynamicDrawTools.push({
-			iconName: 'app-icon app-icon-draw-line',
-			title: '贴地线',
-			id: 'layLine',
-			message: '绘制贴地线'
-		});
-		this.dynamicDrawTools.push({
-			iconName: 'app-icon app-icon-draw-arrow-line',
-			title: '箭头线',
-			id: 'arrowLine',
-			message: '绘制箭头线'
-		});
-		this.dynamicDrawTools.push({
-			iconName: 'app-icon app-icon-draw-dynamic-line',
-			title: '流动线',
-			id: 'dynamicLine',
-			message: '绘制流动线'
-		});
-		this.dynamicDrawTools.push({
-			iconName: 'app-icon app-icon-draw-grow-line',
-			title: '发光线',
-			id: 'glowLine',
-			message: '绘制发光线'
-		});
-		this.dynamicDrawTools.push({
-			iconName: 'app-icon app-icon-draw-outline-line',
-			title: '描边线',
-			id: 'outlineLine',
-			message: '绘制描边线'
-		});
-		this.dynamicDrawTools.push({
-			iconName: 'app-icon app-icon-draw-sline',
-			title: '空间线',
-			id: 'spatialLine',
-			message: '绘制空间线'
-		});
-		this.dynamicDrawTools.push({
-			iconName: 'app-icon app-icon-draw-polygon',
-			title: '贴地面',
-			id: 'layPolygon',
-			message: '绘制贴地面'
-		});
-		this.dynamicDrawTools.push({
-			iconName: 'app-icon app-icon-draw-rectangle',
-			title: '贴地矩形',
-			id: 'layRectangle',
-			message: '绘制贴地矩形'
-		});
-		this.dynamicDrawTools.push({
-			iconName: 'app-icon app-icon-draw-circle',
-			title: '贴地圆',
-			id: 'layCircle',
-			message: '绘制贴地圆'
-		});
-		this.dynamicDrawTools.push({
-			iconName: 'app-icon app-icon-draw-dynamic-circle',
-			title: '扩散圆',
-			id: 'dynamicCircle',
-			message: '绘制扩散圆'
-		});
-		this.dynamicDrawTools.push({
-			iconName: 'app-icon app-icon-draw-dwall',
-			title: '动态围栏',
-			id: 'dynamicWall',
-			message: '绘制动态围栏'
-		});
-		this.dynamicDrawTools.push({
-			iconName: 'app-icon app-icon-draw-wall',
-			title: '普通围栏',
-			id: 'normalWall',
-			message: '绘制普通围栏'
-		});
-		this.dynamicDrawTools.push({
-			iconName: 'app-icon app-icon-draw-text',
-			title: '立体广告',
-			id: 'textBoard',
-			message: '绘制立体广告文字'
-		});
-		this.dynamicDrawTools.push({
-			iconName: 'app-icon app-icon-draw-house',
-			title: '房屋',
-			id: 'house',
-			message: '绘制房屋'
-		});
-		this.dynamicDrawTools.push({
-			iconName: 'app-icon app-icon-draw-video',
-			title: '视频墙',
-			id: 'videoWall',
-			message: '绘制视频墙'
-		});
-		this.dynamicDrawTools.push({
-			iconName: 'app-icon app-icon-draw-odline',
-			title: 'OD线',
-			id: 'odLine',
-			message: '绘制OD线'
-		});
-		this.dynamicDrawTools.push({
-			iconName: 'app-icon app-icon-map-clean',
-			title: '清除标绘',
-			id: 'clear',
-			message: '清除标绘'
-		});
-		this.editParams = DrawTools.initEditPropertyParams();
-	},
-
-	methods: {
-		/**
-		 * 工具点击事件
-		 * @param {String} toolsId 工具Id
-		 */
-		onToolsClick(toolsId) {
-			let _self = this;
-			switch (toolsId) {
-				case 'length':
-					_self.$refs['cmap'].onMeasureLength();
-					break;
-				case 'area':
-					_self.$refs['cmap'].onMeasureArea();
-					break;
-				case 'height':
-					_self.$refs['cmap'].onMeasureHeight();
-					break;
-				case 'space':
-					_self.$refs['cmap'].onMeasureSpatialLength();
-					break;
-				case 'triangle':
-					_self.$refs['cmap'].onMeasureTriangle();
-					break;
-				case 'toolsClear':
-					_self.$refs['cmap'].onToolsClear();
-					break;
-				case 'queryByPolygon':
-					_self.$refs['cmap'].onQueryByPolygon();
-					break;
-				case 'queryByPoint':
-					_self.$refs['cmap'].onQueryByPoint();
-					break;
-				case 'queryByMultiplePoint':
-					_self.$refs['cmap'].onQueryByMultiplePoint();
-					break;
-				case 'queryByLine':
-					_self.$refs['cmap'].onQueryByLine();
-					break;
-				case 'queryByCircle':
-					_self.$refs['cmap'].onQueryByCircle();
-					break;
-				case 'queryByRectangle':
-					_self.$refs['cmap'].onQueryByRectangle();
-					break;
-				case 'layerControl':
-					// _self.$refs['cmap'].onTestDemo();
-					// this.showDialog = true;
-					this.showEditDialog = true;
-					break;
-				case 'dynamicDraw':
-					// _self.$refs['cmap'].onTestDemo();
-					this.showDialog = true;
-					break;
-				case 'cameraView':
-					_self.$refs['cmap'].onGetCameraViewer();
-					break;
-				case 'pick':
-					break;
-				case 'inputLocation':
-					let points = [118.163976, 35.01653, 118.164976, 35.01453, 118.162976, 35.01453];
-					_self.$refs['cmap'].onDrawFeacture(points);
-					break;
-				default:
-					// Dialog.alert({
-					// 	title: '点击了',
-					// 	message: toolsId
-					// });
-					this.dialogVisible = true;
-					break;
-			}
-		},
-
-		closeDialog() {
-			this.showDialog = false;
-		},
-
-		/**
-		 * 标绘工具点击事件
-		 * @param {Object} item 工具项
-		 */
-		onDrawToolsClick(item) {
-			this.$message(item.message);
-			switch (item.id) {
-				case 'layLine':
-					this.$refs['cmap'].onMouseDrawEditLine();
-					break;
-				case 'arrowLine':
-					this.$refs['cmap'].onMouseDrawEditArrowLine();
-					break;
-				case 'dynamicLine':
-					this.$refs['cmap'].onMouseDrawEditDynamicLine();
-					break;
-				case 'glowLine':
-					this.$refs['cmap'].onMouseDrawEditGrawLine();
-					break;
-				case 'outlineLine':
-					this.$refs['cmap'].onMouseDrawEditOutlineLine();
-					break;
-				case 'layPolygon':
-					this.$refs['cmap'].onMouseDrawEditPolygon();
-					break;
-				case 'spatialLine':
-					this.$refs['cmap'].onMouseDrawEditSpatialPolyline();
-					break;
-				case 'layRectangle':
-					this.$refs['cmap'].onMouseDrawEditRectangle();
-					break;
-				case 'layCircle':
-					this.$refs['cmap'].onMouseDrawEditCircle();
-					break;
-				case 'dynamicCircle':
-					this.$refs['cmap'].onMouseDrawDynamicCircle();
-					break;
-				case 'dynamicWall':
-					this.$refs['cmap'].onMouseDrawDynamicEditWall();
-					break;
-				case 'normalWall':
-					this.$refs['cmap'].onMouseDrawColorEditWall();
-					break;
-				case 'textBoard':
-					this.$refs['cmap'].onMouseDrawEditText();
-					break;
-				case 'house':
-					this.$refs['cmap'].onMoouseDrawPolygonBody();
-					break;
-				case 'videoWall':
-					this.$refs['cmap'].onMouseDrawEditVideoWall();
-					break;
-				case 'odLine':
-					this.$refs['cmap'].onMouseDrawEditOdline();
-					break;
-				case 'clear':
-					this.$refs['cmap'].onClearDraw();
-					break;
-			}
-			this.showDialog = false;
-		},
-
-		/**
-		 * 属性编辑调用
-		 * @param {JSON} param 传递的编辑参数
-		 */
-		onEditProperty(param) {
-			// console.log('===传递参数,打开编辑框>>>', param);
-			/* 打开对话框 */
-			this.showEditDialog = true;
-			/* 赋值参数 */
-			for (let key in this.editParams) {
-				this.editParams[key] = param[key];
-			}
-			this.$refs['dialogEdit'].updateParams(this.editParams);
-		},
-
-		/**
-		 * 实体属性提交更改
-		 * @param {JSON} param 参数
-		 */
-		submit(param) {
-			// console.log('===>>>对话框提交的参数', param);
-			this.$refs['cmap'].onSubmitEditProperty(param);
-		},
-
-		/**
-		 * 移除实体
-		 */
-		remove() {
-			this.$refs['cmap'].onRemoveEditEntity();
-		}
-	}
-};
-</script>
-
-<style lang="scss" scoped>
-.cr-color-label {
-	padding-left: 15px;
-	height: 30px;
-	line-height: 30px;
-	color: rgb(144, 225, 255);
-	font-weight: bold;
-	text-align: left;
-	background-color: rgb(29, 99, 248);
-}
-
-/* 弹框子内容容器样式 */
-.cr-popup-content .cr-popup-child-content {
-	padding: 10px;
-	display: flex;
-	flex-direction: column;
-	width: calc(100% - 20px);
-}
-
-/* 弹出框 主要内容 子内容子项通用样式 */
-.cr-popup-content .cr-popup-child-content > * {
-	margin: 10px 0px;
-	font-family: 'Alimama_ShuHeiTi_Bold' !important;
-}
-
-/* 临时设置帧率位置 */
-.cesium-performanceDisplay-defaultContainer {
-	top: unset;
-	bottom: 80px;
-	right: unset;
-	left: 10px;
-}
-
-.jt-slider-button {
-	width: 20px;
-	height: 18px;
-	color: rgb(202, 94, 92);
-	font-size: 10px;
-	line-height: 18px;
-	text-align: center;
-	background-color: rgb(202, 94, 92);
-	border-radius: 100px;
-}
-
-.van-slider {
-	margin: 10px !important;
-	width: calc(100% - 20px) !important;
-}
-
-.cr-edit-buttons {
-	display: flex;
-	flex-direction: row;
-}
-
-.cr-edit-buttons > * {
-	flex: 1;
-	margin-left: 8px !important;
-	height: 34px !important;
-}
-
-.cr-edit-buttons > :first-child {
-	margin-left: 0px !important;
-}
-
-/* 工具框样式 */
-.jt-tools-dialog {
-	top: 0px;
-	.el-col {
-		padding: 10px;
-	}
-
-	.el-col:hover {
-		cursor: pointer;
-		background-color: rgba(0, 0, 0, 0.5);
-	}
-
-	i {
-		display: inline-block;
-		width: 100%;
-		height: 36px;
-		line-height: 36px;
-		text-align: center;
-		border-radius: 5px;
-		font-size: 30px;
-		color: rgba(252, 152, 0, 1);
-		transition: all 0.3s;
-		-webkit-transition: all 0.3s;
-	}
-
-	cite {
-		position: relative;
-		top: 5px;
-		display: block;
-		color: rgba(255, 255, 255, 1);
-		text-overflow: ellipsis;
-		overflow: hidden;
-		white-space: nowrap;
-		font-size: 14px;
-		font-style: normal;
-		text-align: center;
-		font-family: 'Alimama_ShuHeiTi_Bold';
-	}
-}
-</style>
+<template>
+	<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>
+	<view class="cr-tools-right">
+		<ToolButton v-for="(item, index) in rightTools" :id="item.id" :title="item.title" :describe="item.describe"
+			:icon="item.icon" @onclick="onToolsClick" />
+	</view>
+	<jtDialog class="jt-tools-dialog" :showDialog="showDialog" title="动态标绘" height="calc(100% - 50px)" width="300px"
+		top="0px" @closeJTDialog="closeDialog">
+		<el-row :gutter="20">
+			<el-col :span="8" v-for="(item, index) in dynamicDrawTools" @click="onDrawToolsClick(item)">
+				<el-avatar shape="circle" :size="50" style="background-color: bisque;"><i
+						:class="item.iconName" /></el-avatar>
+				<cite>{{ item.title }}</cite>
+			</el-col>
+		</el-row>
+	</jtDialog>
+
+	<!-- 墙的编辑框 -->
+	<dialogEditProperty ref="dialogEdit" :params="editParams" @submit="submit" @remove="remove"
+		v-model:showDialog="showEditDialog"></dialogEditProperty>
+</template>
+<script setup>
+	import {
+		Dialog
+	} from 'vant';
+	/* 引入弹出对话框 */
+	import jtDialog from '../components/jt-dialog/dialog.vue';
+	/* 引入墙的编辑对话框 */
+	import dialogEditProperty from '../components/jt-dialog/dialogEditProperty.vue';
+</script>
+<script>
+	/* 引入三维地图控件 */
+	import CrMap from '../components/CrMap/CrMap.vue';
+	import {
+		DrawTools
+	} from '../components/CrMap/DrawTools.js';
+	import {
+		ref
+	} from 'vue';
+	/* 引入工具按钮 */
+	import ToolButtom from '../components/ToolButton/ToolButton.vue';
+	export default {
+		components: {
+			CrMap
+		},
+		/* 返回数据 */
+		data() {
+			return {
+				leftTools: [],
+				rightTools: [],
+				showOverlay: false,
+				poputNavTitle: '物体样式调整',
+				color: {
+					red: 0,
+					green: 100,
+					blue: 255,
+					alpha: 6
+				},
+				height: 120,
+				dialogVisible: false,
+				showDialog: false,
+				editParams: undefined,
+				showEditDialog: false,
+				dynamicDrawTools: []
+			};
+		},
+		/* 创建 */
+		created() {
+			let _self = this;
+			/* 工具标题初始化 */
+			this.leftTools.push({
+				title: '长度量测',
+				describe: '在地图上点击需要测量对象的特征位置,即可实时计算长度并展示',
+				icon: 'app-icon-map-measurelength',
+				id: 'length'
+			});
+			this.leftTools.push({
+				title: '面积量测',
+				describe: '在地图上点击需要测量的对象特征位置,即可实时计算面积并展示',
+				icon: 'app-icon-map-measurearea',
+				id: 'area'
+			});
+			this.leftTools.push({
+				title: '高度测量',
+				describe: '在地图上点击需要测量的对象特征位置,即可实时计算高度并展示',
+				icon: 'app-icon-map-measureheight',
+				id: 'height'
+			});
+			this.leftTools.push({
+				title: '空间测量',
+				describe: '在地图上点击需要测量的对象特征位置,即可实时计算空间距离并展示',
+				icon: 'app-icon-map-measurespace',
+				id: 'space'
+			});
+			this.leftTools.push({
+				title: '三角测量',
+				describe: '在地图上点击需要测量对象的特征位置,即可实时计算长度并展示',
+				icon: 'app-icon-map-measuretriangle',
+				id: 'triangle'
+			});
+			this.leftTools.push({
+				title: '点击查询',
+				describe: '点击后,在需要查询的位置单击,即可查询该位置的全部可见图层数据',
+				icon: 'app-icon-map-query-point',
+				id: 'queryByPoint'
+			});
+			this.leftTools.push({
+				title: '多点查询',
+				describe: '点击后,在需要查询的位置单击,即可查询该位置的全部可见图层数据',
+				icon: 'app-icon-map-query-multiple-point',
+				id: 'queryByMultiplePoint'
+			});
+			this.leftTools.push({
+				title: '线查询',
+				describe: '点击后,在需要查询的位置单击,即可查询该位置的全部可见图层数据',
+				icon: 'app-icon-map-query-point',
+				id: 'queryByLine'
+			});
+			this.leftTools.push({
+				title: '圆查询',
+				describe: '点击后,在需要查询的位置单击,即可查询该位置的全部可见图层数据',
+				icon: 'app-icon-map-query-point',
+				id: 'queryByCircle'
+			});
+			this.leftTools.push({
+				title: '矩形查询',
+				describe: '点击后,在需要查询的位置单击,即可查询该位置的全部可见图层数据',
+				icon: 'app-icon-map-query-point',
+				id: 'queryByRectangle'
+			});
+			this.leftTools.push({
+				title: '区域查询',
+				describe: '点击后,在地图上绘制查询区域,单击开始查询,即可查询该区域内的全部可见图层数据',
+				icon: 'app-icon-map-query-polygon',
+				id: 'queryByPolygon'
+			});
+			this.leftTools.push({
+				title: '清理绘制',
+				describe: '在地图上单击绘制底部,右键结束绘制拉伸',
+				icon: 'app-icon-map-clean',
+				id: 'toolsClear'
+			});
+
+			this.rightTools.push({
+				title: '图层管理',
+				describe: '点击即可打开图层控制窗口,进行图层及标注的显示/隐藏',
+				icon: 'app-icon-map-layer',
+				id: 'layerControl'
+			});
+			this.rightTools.push({
+				title: '动态标绘',
+				describe: '点击即可打开图层控制窗口,进行图层及标注的显示/隐藏',
+				icon: 'app-icon-tools-draw',
+				id: 'dynamicDraw'
+			});
+			this.rightTools.push({
+				title: '重置地图',
+				describe: '点击即可重置地图范围为初始显示范围',
+				icon: 'app-icon-map-initlocation',
+				id: 'initMapExtent'
+			});
+			this.rightTools.push({
+				title: '坐标查询',
+				describe: '在地图上需要查询坐标的位置上点击,即可查询该位置的地理坐标',
+				icon: 'app-icon-map-querycoord',
+				id: 'coordQuery'
+			});
+			this.rightTools.push({
+				title: '坐标定位',
+				describe: '点击后,弹出坐标输入框,输入正确的位置坐标后点击定位,即可在地图上展示坐标位置',
+				icon: 'app-icon-map-inputcoord-location',
+				id: 'inputLocation'
+			});
+			this.rightTools.push({
+				title: '相机视角',
+				describe: '点击后,弹出坐标输入框,输入正确的位置坐标后点击定位,即可在地图上展示坐标位置',
+				icon: 'app-icon-map-camera-view',
+				id: 'cameraView'
+			});
+			this.rightTools.push({
+				title: '物体拾取',
+				describe: '点击后,在地图上的实体上单击,即可拾取该实体',
+				icon: 'app-icon-map-pick',
+				id: 'pick'
+			});
+			this.rightTools.push({
+				title: '清扫工具',
+				describe: '清除地图上的各类绘制内容',
+				icon: 'app-icon-map-clean',
+				id: 'clear'
+			});
+			/* 动态标绘工具 */
+			this.dynamicDrawTools.push({
+				iconName: 'app-icon app-icon-draw-line',
+				title: '贴地线',
+				id: 'layLine',
+				message: '绘制贴地线'
+			});
+			this.dynamicDrawTools.push({
+				iconName: 'app-icon app-icon-draw-arrow-line',
+				title: '箭头线',
+				id: 'arrowLine',
+				message: '绘制箭头线'
+			});
+			this.dynamicDrawTools.push({
+				iconName: 'app-icon app-icon-draw-dynamic-line',
+				title: '流动线',
+				id: 'dynamicLine',
+				message: '绘制流动线'
+			});
+			this.dynamicDrawTools.push({
+				iconName: 'app-icon app-icon-draw-grow-line',
+				title: '发光线',
+				id: 'glowLine',
+				message: '绘制发光线'
+			});
+			this.dynamicDrawTools.push({
+				iconName: 'app-icon app-icon-draw-outline-line',
+				title: '描边线',
+				id: 'outlineLine',
+				message: '绘制描边线'
+			});
+			this.dynamicDrawTools.push({
+				iconName: 'app-icon app-icon-draw-sline',
+				title: '空间线',
+				id: 'spatialLine',
+				message: '绘制空间线'
+			});
+			this.dynamicDrawTools.push({
+				iconName: 'app-icon app-icon-draw-polygon',
+				title: '贴地面',
+				id: 'layPolygon',
+				message: '绘制贴地面'
+			});
+			this.dynamicDrawTools.push({
+				iconName: 'app-icon app-icon-draw-rectangle',
+				title: '贴地矩形',
+				id: 'layRectangle',
+				message: '绘制贴地矩形'
+			});
+			this.dynamicDrawTools.push({
+				iconName: 'app-icon app-icon-draw-circle',
+				title: '贴地圆',
+				id: 'layCircle',
+				message: '绘制贴地圆'
+			});
+			this.dynamicDrawTools.push({
+				iconName: 'app-icon app-icon-draw-dynamic-circle',
+				title: '扩散圆',
+				id: 'dynamicCircle',
+				message: '绘制扩散圆'
+			});
+			this.dynamicDrawTools.push({
+				iconName: 'app-icon app-icon-draw-dwall',
+				title: '动态围栏',
+				id: 'dynamicWall',
+				message: '绘制动态围栏'
+			});
+			this.dynamicDrawTools.push({
+				iconName: 'app-icon app-icon-draw-wall',
+				title: '普通围栏',
+				id: 'normalWall',
+				message: '绘制普通围栏'
+			});
+			this.dynamicDrawTools.push({
+				iconName: 'app-icon app-icon-draw-text',
+				title: '立体广告',
+				id: 'textBoard',
+				message: '绘制立体广告文字'
+			});
+			this.dynamicDrawTools.push({
+				iconName: 'app-icon app-icon-draw-house',
+				title: '房屋',
+				id: 'house',
+				message: '绘制房屋'
+			});
+			this.dynamicDrawTools.push({
+				iconName: 'app-icon app-icon-draw-video',
+				title: '视频墙',
+				id: 'videoWall',
+				message: '绘制视频墙'
+			});
+			this.dynamicDrawTools.push({
+				iconName: 'app-icon app-icon-draw-odline',
+				title: 'OD线',
+				id: 'odLine',
+				message: '绘制OD线'
+			});
+			this.dynamicDrawTools.push({
+				iconName: 'app-icon app-icon-tools-doodle',
+				title: '涂鸦',
+				id: 'doodle',
+				message: '绘制涂鸦'
+			});
+			this.dynamicDrawTools.push({
+				iconName: 'app-icon app-icon-map-clean',
+				title: '清除标绘',
+				id: 'clear',
+				message: '清除标绘'
+			});
+			this.editParams = DrawTools.initEditPropertyParams();
+		},
+
+		methods: {
+			/**
+			 * 工具点击事件
+			 * @param {String} toolsId 工具Id
+			 */
+			onToolsClick(toolsId) {
+				let _self = this;
+				switch (toolsId) {
+					case 'length':
+						_self.$refs['cmap'].onMeasureLength();
+						break;
+					case 'area':
+						_self.$refs['cmap'].onMeasureArea();
+						break;
+					case 'height':
+						_self.$refs['cmap'].onMeasureHeight();
+						break;
+					case 'space':
+						_self.$refs['cmap'].onMeasureSpatialLength();
+						break;
+					case 'triangle':
+						_self.$refs['cmap'].onMeasureTriangle();
+						break;
+					case 'toolsClear':
+						_self.$refs['cmap'].onToolsClear();
+						break;
+					case 'queryByPolygon':
+						_self.$refs['cmap'].onQueryByPolygon();
+						break;
+					case 'queryByPoint':
+						_self.$refs['cmap'].onQueryByPoint();
+						break;
+					case 'queryByMultiplePoint':
+						_self.$refs['cmap'].onQueryByMultiplePoint();
+						break;
+					case 'queryByLine':
+						_self.$refs['cmap'].onQueryByLine();
+						break;
+					case 'queryByCircle':
+						_self.$refs['cmap'].onQueryByCircle();
+						break;
+					case 'queryByRectangle':
+						_self.$refs['cmap'].onQueryByRectangle();
+						break;
+					case 'layerControl':
+						// _self.$refs['cmap'].onTestDemo();
+						// this.showDialog = true;
+						this.showEditDialog = true;
+						break;
+					case 'dynamicDraw':
+						// _self.$refs['cmap'].onTestDemo();
+						this.showDialog = true;
+						break;
+					case 'cameraView':
+						_self.$refs['cmap'].onGetCameraViewer();
+						break;
+					case 'pick':
+						break;
+					case 'inputLocation':
+						let points = [118.163976, 35.01653, 118.164976, 35.01453, 118.162976, 35.01453];
+						_self.$refs['cmap'].onDrawFeacture(points);
+						break;
+					default:
+						// Dialog.alert({
+						// 	title: '点击了',
+						// 	message: toolsId
+						// });
+						this.dialogVisible = true;
+						break;
+				}
+			},
+
+			closeDialog() {
+				this.showDialog = false;
+			},
+
+			/**
+			 * 标绘工具点击事件
+			 * @param {Object} item 工具项
+			 */
+			onDrawToolsClick(item) {
+				this.$message(item.message);
+				switch (item.id) {
+					case 'layLine':
+						this.$refs['cmap'].onMouseDrawEditLine();
+						break;
+					case 'arrowLine':
+						this.$refs['cmap'].onMouseDrawEditArrowLine();
+						break;
+					case 'dynamicLine':
+						this.$refs['cmap'].onMouseDrawEditDynamicLine();
+						break;
+					case 'glowLine':
+						this.$refs['cmap'].onMouseDrawEditGrawLine();
+						break;
+					case 'outlineLine':
+						this.$refs['cmap'].onMouseDrawEditOutlineLine();
+						break;
+					case 'layPolygon':
+						this.$refs['cmap'].onMouseDrawEditPolygon();
+						break;
+					case 'spatialLine':
+						this.$refs['cmap'].onMouseDrawEditSpatialPolyline();
+						break;
+					case 'layRectangle':
+						this.$refs['cmap'].onMouseDrawEditRectangle();
+						break;
+					case 'layCircle':
+						this.$refs['cmap'].onMouseDrawEditCircle();
+						break;
+					case 'dynamicCircle':
+						this.$refs['cmap'].onMouseDrawDynamicCircle();
+						break;
+					case 'dynamicWall':
+						this.$refs['cmap'].onMouseDrawDynamicEditWall();
+						break;
+					case 'normalWall':
+						this.$refs['cmap'].onMouseDrawColorEditWall();
+						break;
+					case 'textBoard':
+						this.$refs['cmap'].onMouseDrawEditText();
+						break;
+					case 'house':
+						this.$refs['cmap'].onMoouseDrawPolygonBody();
+						break;
+					case 'videoWall':
+						this.$refs['cmap'].onMouseDrawEditVideoWall();
+						break;
+					case 'odLine':
+						this.$refs['cmap'].onMouseDrawEditOdline();
+						break;
+					case 'doodle':
+						this.$refs['cmap'].onMouseDrawDoodle();
+						break;
+					case 'clear':
+						this.$refs['cmap'].onClearDraw();
+						break;
+				}
+				this.showDialog = false;
+			},
+
+			/**
+			 * 属性编辑调用
+			 * @param {JSON} param 传递的编辑参数
+			 */
+			onEditProperty(param) {
+				// console.log('===传递参数,打开编辑框>>>', param);
+				/* 打开对话框 */
+				this.showEditDialog = true;
+				/* 赋值参数 */
+				for (let key in this.editParams) {
+					this.editParams[key] = param[key];
+				}
+				this.$refs['dialogEdit'].updateParams(this.editParams);
+			},
+
+			/**
+			 * 实体属性提交更改
+			 * @param {JSON} param 参数
+			 */
+			submit(param) {
+				// console.log('===>>>对话框提交的参数', param);
+				this.$refs['cmap'].onSubmitEditProperty(param);
+			},
+
+			/**
+			 * 移除实体
+			 */
+			remove() {
+				this.$refs['cmap'].onRemoveEditEntity();
+			}
+		}
+	};
+</script>
+
+<style lang="scss" scoped>
+	.cr-color-label {
+		padding-left: 15px;
+		height: 30px;
+		line-height: 30px;
+		color: rgb(144, 225, 255);
+		font-weight: bold;
+		text-align: left;
+		background-color: rgb(29, 99, 248);
+	}
+
+	/* 弹框子内容容器样式 */
+	.cr-popup-content .cr-popup-child-content {
+		padding: 10px;
+		display: flex;
+		flex-direction: column;
+		width: calc(100% - 20px);
+	}
+
+	/* 弹出框 主要内容 子内容子项通用样式 */
+	.cr-popup-content .cr-popup-child-content>* {
+		margin: 10px 0px;
+		font-family: 'Alimama_ShuHeiTi_Bold' !important;
+	}
+
+	/* 临时设置帧率位置 */
+	.cesium-performanceDisplay-defaultContainer {
+		top: unset;
+		bottom: 80px;
+		right: unset;
+		left: 10px;
+	}
+
+	.jt-slider-button {
+		width: 20px;
+		height: 18px;
+		color: rgb(202, 94, 92);
+		font-size: 10px;
+		line-height: 18px;
+		text-align: center;
+		background-color: rgb(202, 94, 92);
+		border-radius: 100px;
+	}
+
+	.van-slider {
+		margin: 10px !important;
+		width: calc(100% - 20px) !important;
+	}
+
+	.cr-edit-buttons {
+		display: flex;
+		flex-direction: row;
+	}
+
+	.cr-edit-buttons>* {
+		flex: 1;
+		margin-left: 8px !important;
+		height: 34px !important;
+	}
+
+	.cr-edit-buttons> :first-child {
+		margin-left: 0px !important;
+	}
+
+	/* 工具框样式 */
+	.jt-tools-dialog {
+		top: 0px;
+
+		.el-col {
+			padding: 10px;
+		}
+
+		.el-col:hover {
+			cursor: pointer;
+			background-color: rgba(0, 0, 0, 0.5);
+		}
+
+		i {
+			display: inline-block;
+			width: 100%;
+			height: 36px;
+			line-height: 36px;
+			text-align: center;
+			border-radius: 5px;
+			font-size: 30px;
+			color: rgba(252, 152, 0, 1);
+			transition: all 0.3s;
+			-webkit-transition: all 0.3s;
+		}
+
+		cite {
+			position: relative;
+			top: 5px;
+			display: block;
+			color: rgba(255, 255, 255, 1);
+			text-overflow: ellipsis;
+			overflow: hidden;
+			white-space: nowrap;
+			font-size: 14px;
+			font-style: normal;
+			text-align: center;
+			font-family: 'Alimama_ShuHeiTi_Bold';
+		}
+	}
+</style>