超图iClient3DforCesium地形、影像、模型、在线影像交互示例
描述
数据源:基于iserver发布的三维场景(地形、影像、BIM模型) + 在线arcgis影像
应用:目录树展示源数据列表、目录树控制源数据可视化结果显隐、BIM模型点选查询关联属性
示例代码
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=Edge,chrome=1">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, minimum-scale=1, user-scalable=no">
<title>模型交互示例</title>
<link href="../../Build/Cesium/Widgets/widgets.css" rel="stylesheet">
<link href="./css/pretty.css" rel="stylesheet">
<script src="./js/jquery.min.js"></script>
<script src="./js/config.js"></script>
<script src="./js/bootstrap.min.js"></script>
<script src="./js/bootstrap-select.min.js"></script>
<script src="./js/bootstrap-treeview.js"></script>
<script src="./js/spectrum.js"></script>
<script type="text/javascript" src="../../Build/Cesium/Cesium.js"></script>
</head>
<body>
<div id="cesiumContainer"></div>
<div id='tool-menu' class='tool-menu'>
<a data-toggle='dropdown' id='layerMangerBtn' title='图层管理' class='tool-menu-btn tool-menu-btn-inverse'>
<span class='smicon-layerlist tool-menu-btn-icon'></span>
<div class="dropDown-container treeview-dropDown-container" id="treeContainer">
<div id='layerTree'></div>
</div>
</a>
</div>
<div id="bubble" class="bubble" style="bottom:0;left:82%;display:none;" >
<div id="tools" style="text-align : right">
<span style="color: rgb(95, 74, 121);padding: 5px;position: absolute;left: 10px;top: 4px;">对象属性</span>
<span class="fui-export" id="bubblePosition" style="color: darkgrey; padding:5px" title="停靠"></span>
<span class="fui-cross" title="关闭" id="close" style="color: darkgrey;padding:5px"></span>
</div>
<div style="overflow-y:scroll;height:150px" id="tableContainer"><table id="tab"></table></div>
</div>
<script type="text/javascript">
function onload(Cesium) {
// 初始化viewer部件
var viewer = new Cesium.Viewer('cesiumContainer');
var scene = viewer.scene;
var widget = viewer.cesiumWidget;
// 场景光照
scene.lightSource.ambientLightColor = new Cesium.Color(0.65, 0.65, 0.65, 1);
// 添加在线影像服务
let onlineImageries = []; // 在线影像资源对象管理
var arcgisonline = viewer.imageryLayers.addImageryProvider(new Cesium.ArcGisMapServerImageryProvider({
url: 'https://services.arcgisonline.com/arcgis/rest/services/World_Imagery/MapServer'
}), 2);
onlineImageries.push({name: 'arcgis-L17', provider: arcgisonline});
// 对象属性展示载体
var infoboxContainer = document.getElementById("bubble");
viewer.customInfobox = infoboxContainer;
// 添加场景服务
// 场景服务-界面管理图层数组
let loadedLayers = [];
try {
var promise = scene.open('@isever服务地址/iserver/services/3D-publish-workspace/rest/realspace');
Cesium.when(promise, function(layers) {
// 设置相机位置、方向,定位至模型
// 可以先不设置 待第一次渲染的时候 使用console.log()打印出相关参数 来填充此设置
//scene.camera.setView({
// destination : new Cesium.Cartesian3(-2180753.065987198,4379023.266141494,4092583.575045952),
// orientation : {
// heading : 4.0392222751147955,
// pitch :0.010279641987852584,
// roll : 1.240962888005015e-11
// }
//});
// 界面图层管理树形菜单控件
// 初始化树形目录
var $tree = $('#layerTree').treeview({
data: [{text:"图层目录", selectable:false}],
showIcon: true,
showCheckbox: true,
backColor: 'transparent',
color: '#fff',
// 通过NodeChecked状态设置子图层的显示与隐藏的切换
onNodeChecked: function(evt, node) {
// 判断是否选中图层管理节点
if (node.text == "模型图层包") {
// 模型图层的父节点 所有模型图层显隐
for (var i = 0; i < loadedLayers.length; i++) {
if (loadedLayers[i].type == 'model') {
loadedLayers[i].source.visible = true;
}
}
return;
} else if (node.text == "地形图层包") {
// 地形图层的父节点 所有地形图层显隐
for (var i = 0; i < loadedLayers.length; i++) {
if (loadedLayers[i].type == 'terrain') {
viewer.terrainProvider = loadedLayers[i].source;
}
}
return;
} else if (node.text == "影像图层包") {
// 影像图层的父节点 所有影像图层显隐
for (var i = 0; i < loadedLayers.length; i++) {
if (loadedLayers[i].type == 'imagery' || loadedLayers[i].type == 'imagery-online') {
loadedLayers[i].source.show = true;
}
}
return;
} else if (node.text == "图层目录") {
for (var i = 0; i < loadedLayers.length; i++) {
if (loadedLayers[i].type == 'model') {
loadedLayers[i].source.visible = true;
} else if (loadedLayers[i].type == 'terrain') {
viewer.terrainProvider = loadedLayers[i].source;
} else {
loadedLayers[i].source.show = true;
}
}
return;
}
// 判断是否是模型图层
// 先判断是否选中图层的子图层内容
var opLayerIndex = -1;
var ids = [];
for (var i = 0; i < loadedLayers.length; i++) {
// 先判断是否选中了子图层内容
if (loadedLayers[i].type == 'model') {
// 只有模型节点存在子图层内容
for (var j = 0; j < loadedLayers[i].nodes.length; j++) {
if (loadedLayers[i].nodes[j].name == node.text) {
opLayerIndex = i;
ids = range(loadedLayers[i].nodes[j].source.startID, loadedLayers[i].nodes[j].source.endID);
break;
}
}
}
if (opLayerIndex != -1) {
break;
}
// 再判断是否选中的是图层节点本省
if (loadedLayers[i].name == node.text) {
opLayerIndex = i;
break;
}
}
if (ids.length > 0) {
// 设置子图层id对应的内容显隐
loadedLayers[opLayerIndex].source.setOnlyObjsVisible(ids,true);
} else if (opLayerIndex != -1) {
// 图层节点本身
if (loadedLayers[opLayerIndex].type == 'model') {
// 模型图层
loadedLayers[opLayerIndex].source.visible = true;
} else if (loadedLayers[opLayerIndex].type == 'terrain') {
// 地形图层
viewer.terrainProvider = loadedLayers[opLayerIndex].source;
} else {
// 影像图层
loadedLayers[opLayerIndex].source.show = true;
}
}
},
onNodeUnchecked: function(evt, node) {
// 判断是否选中图层管理节点
if (node.text == "模型图层包") {
// 模型图层的父节点 所有模型图层显隐
for (var i = 0; i < loadedLayers.length; i++) {
if (loadedLayers[i].type == 'model') {
loadedLayers[i].source.visible = false;
}
}
return;
} else if (node.text == "地形图层包") {
// 地形图层的父节点 所有地形图层显隐
for (var i = 0; i < loadedLayers.length; i++) {
if (loadedLayers[i].type == 'terrain') {
viewer.terrainProvider = new Cesium.EllipsoidTerrainProvider({}); // 空地形
}
}
return;
} else if (node.text == "影像图层包") {
// 影像图层的父节点 所有影像图层显隐
for (var i = 0; i < loadedLayers.length; i++) {
if (loadedLayers[i].type == 'imagery' || loadedLayers[i].type == 'imagery-online') {
loadedLayers[i].source.show = false;
}
}
return;
} else if (node.text == "图层目录") {
for (var i = 0; i < loadedLayers.length; i++) {
if (loadedLayers[i].type == 'model') {
loadedLayers[i].source.visible = false;
} else if (loadedLayers[i].type == 'terrain') {
viewer.terrainProvider = new Cesium.EllipsoidTerrainProvider({}); // 空地形
} else {
loadedLayers[i].source.show = false;
}
}
return;
}
// 判断是否是模型图层
// 先判断是否选中图层的子图层内容
var opLayerIndex = -1;
var ids = [];
for (var i = 0; i < loadedLayers.length; i++) {
// 先判断是否选中了子图层内容
if (loadedLayers[i].type == 'model') {
// 只有模型节点存在子图层内容
for (var j = 0; j < loadedLayers[i].nodes.length; j++) {
if (loadedLayers[i].nodes[j].name == node.text) {
opLayerIndex = i;
ids = range(loadedLayers[i].nodes[j].source.startID, loadedLayers[i].nodes[j].source.endID);
break;
}
}
}
if (opLayerIndex != -1) {
break;
}
// 再判断是否选中的是图层节点本省
if (loadedLayers[i].name == node.text) {
opLayerIndex = i;
break;
}
}
if (ids.length > 0) {
// 设置子图层id对应的内容显隐
loadedLayers[opLayerIndex].source.setOnlyObjsVisible(ids,false);
} else if (opLayerIndex != -1) {
// 图层节点本身
if (loadedLayers[opLayerIndex].type == 'model') {
// 模型图层
loadedLayers[opLayerIndex].source.visible = false;
} else if (loadedLayers[opLayerIndex].type == 'terrain') {
// 地形图层
viewer.terrainProvider = new Cesium.EllipsoidTerrainProvider({}); // 空地形
} else {
// 影像图层
loadedLayers[opLayerIndex].source.show = false;
}
}
},
onNodeSelected: function(evt, node) {
// 模型节点子图层选中时 模型渲染状态
var opLayerIndex = -1;
var ids = [];
for (var i = 0; i < loadedLayers.length; i++) {
// 先判断是否选中了子图层内容
if (loadedLayers[i].type == 'model') {
// 只有模型节点存在子图层内容
for (var j = 0; j < loadedLayers[i].nodes.length; j++) {
if (loadedLayers[i].nodes[j].name == node.text) {
opLayerIndex = i;
ids = range(loadedLayers[i].nodes[j].source.startID, loadedLayers[i].nodes[j].source.endID);
break;
}
}
}
if (ids.length > 0) {
break;
}
}
if (ids.length > 0) {
loadedLayers[opLayerIndex].source.releaseSelection();
loadedLayers[opLayerIndex].source.setSelection(ids);
} else {
loadedLayers[opLayerIndex].source.removeAllObjsColor();
}
}
});
// 树形目录根节点
var rootNode = $tree.treeview('getNode', 0);
// 属性目录分成三类子节点:
// 第一类: 模型节点
var modelNode = $tree.treeview('addNode', [rootNode, {text:"模型图层包", showDel: true, fontSize: '10pt',
state: {checked: true}}]);
// 第二类: 地形节点
var terrainNode = $tree.treeview('addNode', [rootNode, {text:"地形图层包", showDel: true, fontSize: '10pt',
state: {checked: true}}]);
// 第三类: 影像节点
var imageryNode = $tree.treeview('addNode', [rootNode, {text:"影像图层包", showDel: true, fontSize: '10pt',
state: {checked: true}}]);
// 解析图层 设置图层挂载数据
layers.forEach((layer, index) => {
// 将图层添加到loadedLayers便于管理
if (layer._isS3MB || layer._isS3MBlock) {
// 模型图层
// 模型图层需要查询属性,需要挂载数据
// 设置图层挂载的数据
layer.setQueryParameter({
url: '@isever服务地址/services/data-publish-workspace/rest/data',
dataSourceName: "datasource-publish",
isMerge: true
});
// decodeURI(layer.name)
loadedLayers.push({name: layer.name, checked: true, type: 'model', source: layer, nodes: []});
// 树形目录添加模型图层节点
var childNode = $tree.treeview('addNode', [modelNode, {text: layer.name, showDel: true,
fontSize: '10pt', state: {checked: true}}]);
// 添加当前图层的内容信息
layer.datasetInfo().then(function(result) {
for (var i = 0; i < result.length; i++) {
loadedLayers[loadedLayers.length - 1].nodes.push({name: result[i].datasetName,
checked: true, type: 'model-node', source: result[i], nodes: []});
// 添加到树形目录
$tree.treeview('addNode', [childNode, {text: result[i].datasetName, showDel: true,
fontSize: '10pt', state: {checked: true}}]);
}
});
} else if (layer.imageryProvider) {
// 影像图层
loadedLayers.push({name: decodeURIComponent(layer.imageryProvider.tablename), checked: true, type: 'imagery', source: layer, nodes: []});
// 添加到树形目录
$tree.treeview('addNode', [imageryNode, {text: decodeURIComponent(layer.imageryProvider.tablename), showDel: true,
fontSize: '10pt', state: {checked: true}}]);
} else if (layer._isTerrainZ) {
// decodeURIComponent:可以转换@等特殊字符和中文
// decodeURI:只能转换中文
// 地形图层
loadedLayers.push({name: decodeURIComponent(layer.tablename), checked: true, type: 'terrain', source: layer, nodes: []});
// 添加到树形目录
$tree.treeview('addNode', [terrainNode, {text: decodeURIComponent(layer.tablename), showDel: true,
fontSize: '10pt', state: {checked: true}}]);
}
});
// 更新在线影像图层
onlineImageries.forEach((online, index) => {
// 添加到界面管理图层数组
loadedLayers.push({name: online.name, checked: true, type: 'imagery-online', source: online, nodes: []});
// 添加到树形目录
$tree.treeview('addNode', [imageryNode, {text: online.name, showDel: true,
fontSize: '10pt', state: {checked: true}}]);
});
});
} catch (e) {
if (widget._showRenderLoopErrors) {
var title = '渲染时发生错误,已停止渲染。';
widget.showErrorPanel(title, undefined, e);
}
}
//点击对象查询对象属性
let labelPickedWorker = [
{name: '名字', value: "", key: 'MODELNAME'},
{name: '编码', value: "", key: 'MODELCODE'},
]
var table = document.getElementById("tab");
viewer.pickEvent.addEventListener(function(feature){
$("#bubble").show();
for (i = table.rows.length-1;i > -1;i--){
table.deleteRow(i);
}
for(var key in feature ){
for (var i = 0; i < labelPickedWorker.length; i++) {
if (key == labelPickedWorker[i].key) {
var newRow = table.insertRow();
var cell1 = newRow.insertCell();
var cell2 = newRow.insertCell();
cell1.innerHTML = labelPickedWorker[i].name;
cell2.innerHTML = feature[key];
}
}
}
});
$("#bubblePosition").click(function(){
if($("#bubblePosition").hasClass("fui-export")){
viewer.customInfobox = undefined;
$("#bubble").removeClass("bubble").addClass("float");
$("#bubblePosition").removeClass("fui-export").addClass("fui-bubble");
$("#bubblePosition")[0].title = "悬浮";
$("#bubble").css({'left' : '82%','bottom' : '45%'});
$("#tableContainer").css({'height':'350px'});
}
else if($("#bubblePosition").hasClass("fui-bubble")){
$("#bubble").removeClass("float").addClass("bubble");
$("#bubblePosition").removeClass("fui-bubble").addClass("fui-export");
$("#bubblePosition")[0].title = "停靠";
$("#tableContainer").css({'height':'150px'});
viewer.customInfobox = infoboxContainer;
}
});
$("#close").click(function(){
$("#bubble").hide();
});
function range(startID,endID){
var array=[];
for(var i = startID; i < endID + 1; i++){
array.push(i);
}
return array;
}
//图层目录的隐藏显示
$(document).on('click.dropDown-container touchstart.dropDown-container','[data-toggle=dropdown]',function(evt){
evt.stopPropagation();
var target = evt.target;
if(!target.contains(evt.currentTarget) && target.tagName != 'SPAN'){
return ;
}
var $this = $(this), $parent, isActive;
var $target = $this.children('div.dropDown-container');
if($target.length == 0){
$('.dropDown-container').removeClass('dropDown-visible');
return ;
}
isActive = $target.hasClass('dropDown-visible');
$('.dropDown-container').removeClass('dropDown-visible');
if(!isActive){
$target.addClass('dropDown-visible');
}
return false;
});
var height = $('body').height()*0.85 + 'px';
$('#treeContainer').css({'height' : height,'min-width' : '260px','text-align' : 'left'});
}
if (typeof Cesium !== 'undefined') {
window.startupCalled = true;
onload(Cesium);
}
</script>
</body>
</html>