(三)关于cesium地图的使用:自定义弹窗功能实现

cesium不像高德、百度等有infobox,点击上点图标如果需要特殊样式弹窗,就需要自己定义样式。

之前参考一篇文章,把弹窗dom写在vue的template里面,导致有初始位置,在改变弹窗位置时会有闪烁的效果。此处是先创建dom,

当我指定位置时,再让dom显示。效果很好,不存在闪烁的效果。

1、点击了marker后,执行弹窗。在左键监听事件里执行该点详情接口查询(此处也包含了聚合效果的点击、其他特殊实体被点击)。

// 鼠标左键点击事件
addMouseClick(){
	let that = this;
	window.viewer.screenSpaceEventHandler.setInputAction(function (movement) {
		var pick = window.viewer.scene.pick(movement.position);
		var pickedEntity = Cesium.defined(pick) ? pick.id : undefined; // pick.id即为entity
		// 当是区域查询状态,取消执行其他点击事件,只执行记录点位功能
		if(that.isSelect){
			// 平面坐标(x,y)
			let windowPosition = movement.position;
			// 三维坐标(x,y,z)
			let ellipsoid = window.viewer.scene.globe.ellipsoid;
			let cartesian = window.viewer.camera.pickEllipsoid(windowPosition, window.viewer.scene.globe.ellipsoid);
			// 坐标转换:世界坐标转换为经纬度
			let cartographic = Cesium.Cartographic.fromCartesian(cartesian);
			let lng=Cesium.Math.toDegrees(cartographic.longitude); // 经度
			let lat=Cesium.Math.toDegrees(cartographic.latitude);  // 纬度
			// 经度在前纬度在后
			that.pointPositionList.push(lng);
			that.pointPositionList.push(lat);
			if (!cartesian) {
				return;
			}
			// 实例化空间查询的点实体
			let point = window.viewer.entities.add({
				name: 'gon_point',
				position: cartesian,
				point: {
					color: Cesium.Color.WHITE,
					pixelSize: 10,
					outlineColor: Cesium.Color.BLACK,
					outlineWidth: 1
				}
			});
			// 存储点的实体,用于下图
			that.editPoints.push(point);
			that.polygonPointsEntities.push(cartesian);
			that.polygonPointsEntitiesLine= that.listToArray(that.polygonPointsEntities)
			if (that.editPoints.length > 0) {
				if (that.polygonPointsEntitiesLine.length < 1) return;
				let polyline = window.viewer.entities.add({
					name: "线几何对象",
					polyline: {
						positions: that.polygonPointsEntitiesLine,
						width: 3,
						material: new Cesium.PolylineGlowMaterialProperty({
							color: Cesium.Color.GOLD,
						}),
						depthFailMaterial: new Cesium.PolylineGlowMaterialProperty({
							color: Cesium.Color.GOLD,
						}),
					}
				});
				// 存储线的实体,用于下图
				that.polygonPointsEntitiesEntity.push(polyline)
			}
			// 大于三个点开始画面
			if (that.polygonPointsEntities.length >= 3) {
				if (!that.polygonEntity) {
					that.polygonEntity = window.viewer.entities.add({
						name: 'polygon',
						polygon: {
							hierarchy: new Cesium.CallbackProperty(() => {
								return new Cesium.PolygonHierarchy(that.polygonPointsEntities);
							}, false),
							material: new Cesium.Color.fromCssColorString("#4296FF").withAlpha(0.4)
						}
					});
				} else {
					that.polygonEntity.polygon.hierarchy = new Cesium.CallbackProperty(() => {
						return new Cesium.PolygonHierarchy(that.polygonPointsEntities);
					}, false);
				}
			}
		}else if (pickedEntity && pickedEntity.database && pickedEntity.database.id && pickedEntity.resourceIcon) {
			// 点击资源前,若有选中的先将之前资源状态复原,图标正常显示
			if (that.curBillboard) {
				that.curBillboard.billboard.image = that.staticFileUrl + that.curBillboard.resourceIcon.icon;
				that.curBillboard = null;
			}
			that.curBillboard = pickedEntity;
			// 点击后,高亮当前资源
			if (that.curBillboard && that.curBillboard.billboard) {
				that.curBillboard.billboard.image =that.staticFileUrl + that.curBillboard.resourceIcon.highlightIcon;
			}
			// 将当前资源的经纬度转为像素坐标系,为当前资源详情框的相对位置
			var scratch = new Cesium.Cartesian2();
			var position = Cesium.Cartesian3.fromDegrees(
				Number(that.curBillboard.database.longitude),
				Number(that.curBillboard.database.latitude)
			);
			var canvasPosition = Cesium.SceneTransforms.wgs84ToWindowCoordinates(
				window.viewer.scene,
				position,
				scratch
			);
			if (Cesium.defined(canvasPosition)) {
				that.curBillboard.database.position = canvasPosition;
				// 查询详情接口
				that.getResourceDetailById(that.curBillboard);
			}
			return false;
		} else if (Array.isArray(pickedEntity)) {
			// 聚合类的点击
			// 点击聚合,相机高度降低一定范围
			let clickPosition = viewer.scene.globe.pick(
				viewer.camera.getPickRay(movement.position),
				viewer.scene
			);
			var ellipsoid = viewer.scene.globe.ellipsoid;
			var cartographic = ellipsoid.cartesianToCartographic(
				clickPosition
			);
			var lat = Cesium.Math.toDegrees(cartographic.latitude);
			var lng = Cesium.Math.toDegrees(cartographic.longitude);
			var alt = cartographic.height;

			let curPosition = that.getCenterPosition();
			let height = curPosition.height / 2;

			let heading = window.viewer.camera.heading;
			window.viewer.camera.flyTo({
				destination: Cesium.Cartesian3.fromDegrees(
					lng,
					lat,
					height
				),
				duration: 2,
			});
		}
	},Cesium.ScreenSpaceEventType.LEFT_CLICK);
},

2、getResourceDetailById(),查询marker的详细信息

// 根据点击的图标查询实体详情
getResourceDetailById(entity) {
	this.axios.get(`${twoMap.getResourceDetailById}/${entity.resourceIcon.code}/${entity.database.id}`).then(res =>{
		if (res) {
			const data = res.data;
			// 将所有可枚举属性的值从一个或多个源对象复制到目标对象。它将返回目标对象。
			entity.database = Object.assign(
				entity.database,
				data.data
			);
			// resDetails描绘弹窗内容
			this.curBillboard.content = this.resDetails(
				entity.database,
				entity.resourceIcon.code,
				entity.resourceIcon.name
			);
			this.infoWindow.setVisible(true);
			this.infoWindow.showAt(
				this.curBillboard.database.position,
				this.curBillboard.content
			);
			// 监听弹窗关闭事件
			let _self = this;
			document.getElementById("closeWkk").onclick = function (e) {
					_self.closeDialog();
				};
			// 监听三维实景按钮点击事件
			document.getElementById("threeMap").onclick = function (e) {
				// _self.setChartType("THREEMAP");
				localStorage.setItem('enterId',entity.database.id)
				let url =
					window.location.href.substring(
							0,
							window.location.href.indexOf("safetyProduction.html")
						) + "threeDimensional.html";
					window.open(url, "_blank"); // 打开三维实景新页
			};
			// 监听企业画像按钮点击事件
			document.getElementById("componenyInfo").onclick = function (e) {
				_self.$store.state.dialog.dialogEnterpriseDialog={
					show:true,
					enterId:entity.database.id
				}
			};
		}
	});
},

3、描绘弹窗内容resDetails()

// 信息弹窗内容
resDetails(data, code, name, type, from) {
	let markerContent = `<div class="dialog">
		<div class="title">${data.tailingName}</div>
		<div class="line"></div>
		<div class="close-dialog" id="closeWkk"></div>
		<ul>
			<li>
				<div>${data.gradeName}</div>
				<div>等别</div>
			</li>
			<li>
				<div>${data.riskIndex}</div>
				<div>风险指数</div>
			</li>
			<li>
				<div>${data.planCapability}万</div>
				<div>设计库容</div>
			</li>
			<li>
				<div>${data.nowVolume}万</div>
				<div>现状库容</div>
			</li>
			<li>
				<div>${data.designHeight}</div>
				<div>设计坝高</div>
			</li>
			<li>
				<div>${data.stackHeight}</div>
				<div>现状坝高</div>
			</li>
			<li>
				<div>${data.operatingStatusName}</div>
				<div>状态</div>
			</li>
			<li>
				<div>${data.unitName}</div>
				<div>责任单位</div>
			</li>
		</ul>
		<div class="btnCommonBox">
			<div class="btnCommon" style="margin-right:30px;" id="threeMap">三维实景</div>
			<div class="btnCommon" id="componenyInfo">企业画像</div>
		</div>
	</div>`;
	let div = document.createElement("div");
	div.innerHTML = markerContent;
	return div;
},

4、infoWindow的显示(setVisible())和位置控制(showAt()),要在地图初始化的地方声明气泡窗体对象(initTool())

// 声明气泡窗体
setInfoWindow(className) {
	var isInit = false;
	let that = this,
		infoWindow = function () { };
	infoWindow.initTool = function (frameDiv) {
		if (isInit) {
			return;
		}
		var div = document.createElement("DIV");
		this._div = div;
		this._div.style.position = "absolute";
		this._div.style.cursor = "pointer";
		// this._div.style.zIndex = "3";
		this._div.className = className;
		frameDiv.appendChild(div);
		isInit = true;
	};

	infoWindow.setVisible = function (visible) {
		if (!isInit) {
			return;
		}
		this._div.style.display = visible ? "block" : "none";
		if (!visible) {
			this._div.innerHTML = "";
		}
	};
	// position屏幕坐标
	infoWindow.showAt = function (position, content,type) {
		if (!isInit) {
			return;
		}
		// 不同类型弹窗,调整适合的位置
		if (position && type !== 'dizhendai') {
			if (content) {
				this._div.innerHTML = "";
				this._div.appendChild(content);
			}
			this._div.style.left = (position.x - 220) + "px";
			this._div.style.top = (position.y - 410) + "px";
		}else if(position && type == 'dizhendai') {
			if (content) {
				this._div.innerHTML = "";
				this._div.appendChild(content);
			}
			this._div.style.left = (position.x - 30) + "px";
			this._div.style.top = (position.y - 100) + "px";
		}
	};
	
	return infoWindow;
},

 

  • 0
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

山为樽水为沼

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值