(三)关于cesium地图的使用:自定义弹窗功能实现
cesium不像高德、百度等有infobox,点击上点图标如果需要特殊样式弹窗,就需要自己定义样式。之前参考一篇文章,把弹窗dom写在vue的template里面,导致有初始位置,在改变弹窗位置时会有闪烁的效果。此处是先创建dom,当我指定位置时,再让dom显示。效果很好,不存在闪烁的效果。1、点击了marker后,执行弹窗...
·
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;
},
更多推荐
已为社区贡献6条内容
所有评论(0)