打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
cesium 3dtiles模型单体化点击高亮效果

前言

cesium 官网的api文档介绍地址cesium官网api,里面详细的介绍 cesium 各个类的介绍,还有就是在线例子:cesium 官网在线例子,这个也是学习 cesium 的好素材。

cesium官网在线例子

https://sandcastle.cesium.com/?src=3D+Tiles+Feature+Picking.html

大概思路如下:

  • 加载3dtiles模型

var tileset = new Cesium.Cesium3DTileset({
url: Cesium.IonResource.fromAssetId(75343),
});
viewer.scene.primitives.add(tileset);
  • 创建html元素,鼠标移动以及点击模型高亮作用

// HTML overlay for showing feature name on mouseovervar nameOverlay = document.createElement("div");
viewer.container.appendChild(nameOverlay);
nameOverlay.className = "backdrop";
nameOverlay.style.display = "none";
nameOverlay.style.position = "absolute";
nameOverlay.style.bottom = "0";
nameOverlay.style.left = "0";
nameOverlay.style["pointer-events"] = "none";
nameOverlay.style.padding = "4px";
nameOverlay.style.backgroundColor = "black";
  • 设置选中要素的样式以及创建选中模型

// Information about the currently selected featurevar selected = {
feature: undefined,
originalColor: new Cesium.Color(),
}; 
// An entity object which will hold info about the currently selected feature for infobox displayvar selectedEntity = new Cesium.Entity();
  • 鼠标响应事件交互

// 获取默认的左键单击处理程序,用于在左键单击时未拾取要素var clickHandler = viewer.screenSpaceEventHandler.getInputAction(
Cesium.ScreenSpaceEventType.LEFT_CLICK
); 
// 如果支持剪影,则鼠标上方的剪影功能为蓝色,鼠标单击的剪影功能为绿色// 如果不支持轮廓,请将特征颜色更改为鼠标悬停时为黄色,单击鼠标时为绿色if (
Cesium.PostProcessStageLibrary.isSilhouetteSupported(viewer.scene)
) {// 支持轮廓var silhouetteBlue = Cesium.PostProcessStageLibrary.createEdgeDetectionStage();
silhouetteBlue.uniforms.color = Cesium.Color.BLUE;//蓝色silhouetteBlue.uniforms.length = 0.01;
silhouetteBlue.selected = []; 
var silhouetteGreen = Cesium.PostProcessStageLibrary.createEdgeDetectionStage();
silhouetteGreen.uniforms.color = Cesium.Color.LIME;
silhouetteGreen.uniforms.length = 0.01;
silhouetteGreen.selected = [];
 
viewer.scene.postProcessStages.add(
Cesium.PostProcessStageLibrary.createSilhouetteStage([
silhouetteBlue,
silhouetteGreen,
])
); 
// 在悬停时勾勒出蓝色的轮廓viewer.screenSpaceEventHandler.setInputAction(function onMouseMove(
movement
) {// 如果先前高亮显示了某个要素,请撤消该高亮显示silhouetteBlue.selected = []; 
//点击新要素var pickedFeature = viewer.scene.pick(movement.endPosition);if (!Cesium.defined(pickedFeature)) {
nameOverlay.style.display = "none";return;
} 
//要素被点击,显示它的覆盖内容nameOverlay.style.display = "block";
nameOverlay.style.bottom =viewer.canvas.clientHeight - movement.endPosition.y + "px";
nameOverlay.style.left = movement.endPosition.x + "px";var name = pickedFeature.getProperty("BIN");
nameOverlay.textContent = name; 
// 突出显示尚未选定的功能if (pickedFeature !== selected.feature) {
silhouetteBlue.selected = [pickedFeature];
}
},
Cesium.ScreenSpaceEventType.MOUSE_MOVE); 
// 在信息框中显示选定内容和元数据viewer.screenSpaceEventHandler.setInputAction(function onLeftClick(
movement
) {// 如果先前选择了某个特征,请撤消高亮显示silhouetteGreen.selected = []; 
// 点击新要素var pickedFeature = viewer.scene.pick(movement.position);if (!Cesium.defined(pickedFeature)) {
clickHandler(movement);return;
} 
// Select the feature if it's not already selectedif (silhouetteGreen.selected[0] === pickedFeature) {return;
} 
// 保存选定要素的原始颜色var highlightedFeature = silhouetteBlue.selected[0];if (pickedFeature === highlightedFeature) {
silhouetteBlue.selected = [];
} 
// 高亮新选择要素silhouetteGreen.selected = [pickedFeature]; 
// 设置要素信息框描述var featureName = pickedFeature.getProperty("name");
selectedEntity.name = featureName;
selectedEntity.description =
'Loading <div class="cesium-infoBox-loading"></div>';
viewer.selectedEntity = selectedEntity;
selectedEntity.description =
'<table class="cesium-infoBox-defaultTable"><tbody>' +
"<tr><th>BIN</th><td>" +pickedFeature.getProperty("BIN") +
"</td></tr>" +
"<tr><th>DOITT ID</th><td>" +pickedFeature.getProperty("DOITT_ID") +
"</td></tr>" +
"<tr><th>SOURCE ID</th><td>" +pickedFeature.getProperty("SOURCE_ID") +
"</td></tr>" +
"</tbody></table>";
},
Cesium.ScreenSpaceEventType.LEFT_CLICK);
} else {// 不支持轮廓。相反,更改特征颜色// 有关当前突出显示的功能的信息var highlighted = {
feature: undefined,
originalColor: new Cesium.Color(),
}; 
// 鼠标移动显示黄色viewer.screenSpaceEventHandler.setInputAction(function onMouseMove(
movement
) {// 如果先前高亮显示了某个要素,请撤消该高亮显示if (Cesium.defined(highlighted.feature)) {
highlighted.feature.color = highlighted.originalColor;
highlighted.feature = undefined;
}// 点击新要素var pickedFeature = viewer.scene.pick(movement.endPosition);if (!Cesium.defined(pickedFeature)) {
nameOverlay.style.display = "none";return;
}// 要素被点击,显示它的覆盖内容nameOverlay.style.display = "block";
nameOverlay.style.bottom =viewer.canvas.clientHeight - movement.endPosition.y + "px";
nameOverlay.style.left = movement.endPosition.x + "px";var name = pickedFeature.getProperty("name");if (!Cesium.defined(name)) {
name = pickedFeature.getProperty("id");
}
nameOverlay.textContent = name;// Highlight the feature if it's not already selected.if (pickedFeature !== selected.feature) {
highlighted.feature = pickedFeature;
Cesium.Color.clone(
pickedFeature.color,
highlighted.originalColor
);
pickedFeature.color = Cesium.Color.YELLOW;
}
},
Cesium.ScreenSpaceEventType.MOUSE_MOVE); 
//为所选内容上色并在信息框中显示元数据viewer.screenSpaceEventHandler.setInputAction(function onLeftClick(
movement
) {// 如果先前选择了某个特征,请撤消高亮显示if (Cesium.defined(selected.feature)) {
selected.feature.color = selected.originalColor;
selected.feature = undefined;
}// 点击新要素var pickedFeature = viewer.scene.pick(movement.position);if (!Cesium.defined(pickedFeature)) {
clickHandler(movement);return;
}// Select the feature if it's not already selectedif (selected.feature === pickedFeature) {return;
}
selected.feature = pickedFeature;// Save the selected feature's original colorif (pickedFeature === highlighted.feature) {
Cesium.Color.clone(
highlighted.originalColor,
selected.originalColor
);
highlighted.feature = undefined;
} else {
Cesium.Color.clone(pickedFeature.color, selected.originalColor);
}// Highlight newly selected featurepickedFeature.color = Cesium.Color.LIME;// Set feature infobox descriptionvar featureName = pickedFeature.getProperty("name");
selectedEntity.name = featureName;
selectedEntity.description =
'Loading <div class="cesium-infoBox-loading"></div>';
viewer.selectedEntity = selectedEntity;
selectedEntity.description =
'<table class="cesium-infoBox-defaultTable"><tbody>' +
"<tr><th>BIN</th><td>" +pickedFeature.getProperty("BIN") +
"</td></tr>" +
"<tr><th>DOITT ID</th><td>" +pickedFeature.getProperty("DOITT_ID") +
"</td></tr>" +
"<tr><th>SOURCE ID</th><td>" +pickedFeature.getProperty("SOURCE_ID") +
"</td></tr>" +
"<tr><th>Longitude</th><td>" +pickedFeature.getProperty("longitude") +
"</td></tr>" +
"<tr><th>Latitude</th><td>" +pickedFeature.getProperty("latitude") +
"</td></tr>" +
"<tr><th>Height</th><td>" +pickedFeature.getProperty("height") +
"</td></tr>" +
"<tr><th>Terrain Height (Ellipsoid)</th><td>" +pickedFeature.getProperty("TerrainHeight") +
"</td></tr>" +
"</tbody></table>";
},
Cesium.ScreenSpaceEventType.LEFT_CLICK);

其他小专栏例子:3dtiles单体化

https://xiaozhuanlan.com/topic/3241096587
具体看上述链接文章,里面有详细的介绍

本篇文章效果例子:结合geoserver实现3dtiles倾斜模型单体化点击高亮

实现思路如下:鼠标点击倾斜模型,获取对应的点击坐标点;然后根据pick获取到的坐标点,结合geoserver发布的wfs服务,进行空间查询,匹配对应的geojson数据;最后根据获取到的geojson数据源来绘制显示高亮效果,并且弹出对应气泡窗口。

效果图:

  • 监听鼠标点击事件:

this.handler.setInputAction(function (evt) { //单机开始绘制var picks = viewer.scene.drillPick(evt.position);
viewer.scene.render();var cartesian;var isOn3dtiles = false;for (var i = 0; i < picks.length; i++) {if ((picks[i] && picks[i].primitive) || picks[i] instanceof Cesium.Cesium3DTileFeature) { //模型上拾取isOn3dtiles = true;
}
}if (isOn3dtiles) {
cartesian = viewer.scene.pickPosition(evt.position);var lnglat = cUtil.cartesianToLnglat(cartesian);//坐标转换that.queryWFSData([lnglat]);
} else {
console.warn("请到模型上拾取!");return;
}
}, Cesium.ScreenSpaceEventType.LEFT_CLICK);
queryWFSData: function (lnglats) {if (!lnglats || lnglats.length < 1) return;var that = this;
queryWFSData({
typeName: typeName,
propertyName: propertyName,
url: mapUrl,
queryData: {
type: '1',
coors: lnglats
},
success: function (data) {if (!data.features || data.features.length == 0) {
console.warn("未查询到相关数据!");return;
}
that.loadGeojson(data);//查询结果高亮绘制显示}
})
}
  • 高亮绘制显示:

loadGeojson: function (data) {if (!data) return;var that = this;
Cesium.GeoJsonDataSource.load(data, {
stroke: Cesium.Color.HOTPINK,
fill: Cesium.Color.YELLOW.withAlpha(.8),
clampToGround: true,
strokeWidth: 3}).then(function (dataSource) {
that.quyerDataSourceArr.push(dataSource);
viewer.dataSources.add(dataSource);var entities = dataSource.entities.values;
that.bindPopup(entities);
viewer.flyTo(entities, {
offset: new Cesium.HeadingPitchRange(0, Cesium.Math.toRadians(-90.0), 100)
});
});
}
  • 气泡窗口显示:

bindPopup: function (entities) {if (!entities || entities.length < 1) return;var that = this;
entities.forEach(function (ent) {
ent.attr = "loadgeojson";var properties = ent._properties;var contentStr = "";for (var i in properties) {var name = ppObj[i];var value = properties[i]._value;if (name && value) {
contentStr +=`<tr>
<td>${name}</td>
<td>${value}</td>
</tr>`;
}
}var content =`<table style='width:200px;'>${contentStr}</table>`;//绑定弹窗var hierarchy = ent.polygon.hierarchy._value.positions;var center = cUtil.getCenterByPositions(hierarchy);var lnglat = cUtil.cartesianToLnglat(center);var tileH = viewer.scene.sampleHeight(Cesium.Cartographic.fromDegrees(lnglat[0], lnglat[1]));var popupCartesian = Cesium.Cartesian3.fromDegrees(lnglat[0], lnglat[1], tileH);var popup = new MovePrompt(viewer, {
type: 2,
content: content,
popupCartesian: popupCartesian,
offset: {
y: -30}
})
that.popupArr.push(popup);
ent.popup = popup;
});
}

更多精彩文章,见下面的cesium小专栏

GIS之家/Cesium专题 - 小专栏xiaozhuanlan.com

本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
【热】打开小程序,算一算2024你的财运
Cesium 基于MapBox底图加载3DTiles 模型
Cesium案例解析(五)——3DTilesPhotogrammetry摄影测量3DTiles数据
Cesium学习(2)
Cesium专栏-淹没分析(附源码下载)
cesium-绘制点、线、面
Cesium案例解析(十)——CZML点
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服