利用renderjs挂载cesium,通过renderjs层和逻辑层之间通信,实现拾取要素传输属性并弹窗展示
<template>
<view class="content">
<!-- #ifdef APP-PLUS || H5 -->
<u-modal :show="showGd" title="管点信息" @confirm="confirm" :closeOnClickOverlay="true" confirmText="关闭">
<view class="slot-content">
<view>
<text class="blue">管点名称:{{ porperty.name }}</text>
</view>
<view>
<text class="blue">管线子类码:{{ porperty["管线子类码"] }}</text>
</view>
<view>
<text class="blue">点编码:{{ porperty["点编码"] }}</text>
</view>
<view>
<text class="blue">物探点号:{{ porperty["物探点号"] }}</text>
</view>
<view>
<text class="blue">管点类型:{{ porperty["管线类型"] }}</text>
</view>
<view>
<text class="blue">附属物:{{ porperty["附属物"] }}</text>
</view>
<view>
<text class="blue">图上点号:{{ porperty["图上点号"] }}</text>
</view>
<view>
<text class="blue">图幅号:{{ porperty["图幅号"] }}</text>
</view>
<view>
<text class="blue">井深:{{ porperty["井深"] }}</text>
</view>
<view>
<text class="blue">井盖材质:{{ porperty["井盖材质"] }}</text>
</view>
<view>
<text class="blue">井盖规格:{{ porperty["井盖规格"] }}</text>
</view>
<view>
<text class="blue">偏心井位:{{ porperty["偏心井位"] }}</text>
</view>
<view>
<text class="blue">地面高程:{{ porperty["地面高程"] }}</text>
</view>
<view>
<text class="blue">特征:{{ porperty["特征"] }}</text>
</view>
<view>
<text class="blue">备注:{{ porperty["备注"] }}</text>
</view>
</view>
</u-modal>
<u-modal :show="showGx" title="管线信息" @confirm="confirm" :closeOnClickOverlay="true"
confirmText="关闭">
<view class="slot-content">
<view>
<text class="blue">管线名称:{{ porperty["name"] }}</text>
</view>
<view>
<text class="blue">点编码:{{ porperty["点编码"] }}</text>
</view>
<view>
<text class="blue">物探点号:{{ porperty["物探点号"] }}</text>
</view>
<view>
<text class="blue">管线子类码:{{ porperty["管线子类码"] }}</text>
</view>
<view>
<text class="blue">管线类型:{{ porperty["管线类型"] }}</text>
</view>
<view>
<text class="blue">管线起点号:{{ porperty["管线起点号"] }}</text>
</view>
<view>
<text class="blue">管线终点号:{{ porperty["管线终点号"] }}</text>
</view>
<view>
<text class="blue">井深:{{ porperty["井深"] }}</text>
</view>
<view>
<text class="blue">图上点号:{{ porperty["图上点号"] }}</text>
</view>
<view>
<text class="blue">图幅号:{{ porperty["图幅号"] }}</text>
</view>
<view>
<text class="blue">地面高程:{{ porperty["地面高程"] }}</text>
</view>
<view>
<text class="blue">埋设类型:{{ porperty["埋设类型"] }}</text>
</view>
<view>
<text class="blue">材质:{{ porperty["材质"] }}</text>
</view>
<view>
<text class="blue">特征:{{ porperty["特征"] }}</text>
</view>
<view>
<text class="blue">管径:{{ porperty["管径"] }}</text>
</view>
<view>
<text class="blue">起点埋深:{{ porperty["起点埋深"] }}</text>
</view>
<view>
<text class="blue">终点埋深:{{ porperty["终点埋深"] }}</text>
</view>
<view>
<text class="blue">起点管顶高:{{ porperty["起点管顶高"] }}</text>
</view>
<view>
<text class="blue">终点管顶高:{{ porperty["终点管顶高"] }}</text>
</view>
<view>
<text class="blue">附属物:{{ porperty["附属物"] }}</text>
</view>
<view>
<text class="blue">备注:{{ porperty["备注"] }}</text>
</view>
</view>
</u-modal>
<view id="container" :deviceFlyTo="deviceFlyTo" :change:deviceFlyTo="CesiumMap.updateFlyTo"
:currentSection="currentSection" :change:currentSection="CesiumMap.onUpdateTestChange"
:resYhd="resYhd" :change:resYhd="CesiumMap.queryMessage"
:Json="Json" :change:Json="CesiumMap.fetchTilesJson"
></view>
<!-- #endif -->
</view>
</template>
逻辑层代码
import request from '@/utils/request';
export default {
props: {
currentSection: {
type: Number,
default: 0
},
deviceFlyTo: {
type: Array,
default: []
}
},
data() {
return {
resYhd: [],
Json: [],
showGd: false,
showGx: false,
porperty:{},
}
},
methods: {
confirm() {
this.showGd = false;
this.showGx = false;
},
reciveMessage(val) {
if(val){
this.fetch3DTilesSources();
}
},
recivePorperty(val){
if(val){
console.log("收到的实体属性",val)
this.porperty = val
if (this.porperty.batchId && this.porperty.batchId.indexOf("管线") !== -1) {
this.showGx = true
} else if(this.porperty.batchId && this.porperty.batchId.indexOf("管点") !== -1){
this.showGd = true
}
}
},
// 假设你有一个函数来获取3D Tiles数据源列表
async fetch3DTilesSources() {
try {
// 这里的uni.request因为框架搭建问题,可能不是识别,因此加上了uni.;axios在app模拟器中报错,因此使用的request
const response = await uni.request({
// 这里我把所有3Dtile的url以列表的方式写成了json,放在后端通过请求获得,也可放在静态资源中
url: '换成你的url/3Dtiles.json',
method: 'GET',
});
this.Json = response.data; // 假设返回的是包含URLs的数组
}
catch (error) {
console.error('Failed to fetch 3D Tiles sources:', error);
}
},
}}
renderjs层,
<script module="CesiumMap" lang="renderjs">
export default {
data() {
return {
domlist: null, // 动态引入dom标签合集
viewer: null, // 三维视窗
curMap: Number, // 接收逻辑层的currentSection
flyto: Array, // 接收逻辑层的flyto
imageryProvidersList: [],
tempList: [],
dataList: [],
propertiesList:{},
selectedEntity: null,
}
},
mounted() {
this.initResources(); // 初始化cesium
},
methods: {
sendMsg(){
// 向逻辑层传参,确保cesium资源请求完成,即viewer已存在
this.$ownerInstance.callMethod('reciveMessage', 1)
},
sendSelectPorperty(data){
// 向页面传参,传递属性数据
this.$ownerInstance.callMethod('recivePorperty', data)
},
fetchTilesJson(newVal, oldVal, ownerInstance, instance){
// console.log("renderjs层收到的json", newVal)
if (this.viewer && newVal !== null && newVal.length > 0){
this.setup3DtilesAll(newVal, this.viewer)
}
},
// 初始化资源,加载后例化cesium
initResources() {
if (this.domlist) {
this.removeResource()
} else {
// 动态引入css文件
const linkDom = document.createElement('link')
linkDom.rel = "stylesheet"
//linkDom.href = "static/Cesium/Widgets/widgets.css"
linkDom.href = "http://xxxxxx/Cesium/Widgets/widgets.css"
// linkDom.href = "https://cesium.com/downloads/cesiumjs/releases/1.84/Build/Cesium/Widgets/widgets.css"
document.head.appendChild(linkDom)
var cesiumS = this.requireResources('script', 'http://xxxxxx/Cesium/Cesium.js', this
.initCesium)
//var cesiumS = this.requireResources('script', 'static/Cesium/Cesium.js', this.initCesium)
// var cesiumS = this.requireResources('script',
// 'https://cesium.com/downloads/cesiumjs/releases/1.84/Build/Cesium/Cesium.js', this.initCesium)
this.domlist = [linkDom, cesiumS]
}
},
// 动态创建script引用第三方类库
requireResources(dom, src, callback) {
// 动态引入较大类库避免影响页面展示
const script = document.createElement(dom)
// view 层的页面运行在 www 根目录,其相对路径相对于 www 计算
script.src = src;
document.head.appendChild(script);
callback && (callback instanceof Function) && (script.onload = callback.bind(this));
return script
},
// 移除动态添加的标签,避免重复添加标签
removeResource() {
if (this.domlist)
for (let i = 0; i < this.domlist.length; i++) {
document.head.removeChild(this.domlist[i])
}
},
// 初始化
initCesium() {
Cesium.Ion.defaultAccessToken =
"tk";
this.viewer = new Cesium.Viewer('container', {
// terrainProvider: Cesium.createWorldTerrain(), // 创建世界地形
geocoder: false, //右上角 搜索
homeButton: false, //右上角 Home
// sceneModePicker: false, //右上角 2D/3D切换
baseLayerPicker: false, //右上角图层选择器
navigationHelpButton: false, //右上角 Help
animation: false, // 左下角 圆盘动画控件
timeline: false, //时间轴
fullscreenButton: false, //右下角 全屏控件
vrButton: false, // 如果设置为true,将创建VRButton小部件。
scene3DOnly: true, // 每个几何实例仅以3D渲染以节省GPU内存
infoBox: false, //隐藏点击要素后的提示信息
selectionIndicator: false, //绿色的定位框
// 加载天地图底图
imageryProvider: new Cesium.WebMapTileServiceImageryProvider({
url: 'http://t0.tianditu.gov.cn/img_w/wmts?tk=tk',
layer: 'img',
style: 'default',
tileMatrixSetID: 'w',
format: 'tiles',
maximumLevel: 18
}),
})
this.viewer._cesiumWidget._creditContainer.style.display = 'none'; //隐藏版本信息
this.viewer.scene.debugShowFramesPerSecond = false; // 显示帧数
this.setupClickListener();
this.sendMsg();
},
// 遍历json添加3Dtiles数据
setup3DtilesAll(tilesetUrls, viewer) {
let boundingSpheres = [];
tilesetUrls.forEach(tilesetUrl => {
let tileset = viewer.scene.primitives.add(new Cesium.Cesium3DTileset({
url: tilesetUrl,
}));
tileset.readyPromise.then(() => {
viewer.scene.globe.depthTestAgainstTerrain = true;
let boundingSphere = tileset.boundingSphere;
if (boundingSphere) {
boundingSpheres.push(boundingSphere);
}
// 检查是否所有Tilesets都已加载
if (boundingSpheres.length === tilesetUrls.length) {
// 所有Tilesets都已加载,执行定位飞行
this.flyToBoundingSpheres(boundingSpheres, viewer);
}
}).otherwise(function(error) {
throw (error);
});
});
},
flyToBoundingSpheres(boundingSpheres, viewer) {
// 如果有多个包围球,可以根据实际情况选择合适的策略来确定最终飞行的目标位置
// 例如,可以选择最大的包围球中心,或者计算所有包围球中心的平均值等
if (boundingSpheres.length > 0) {
let targetBoundingSphere = boundingSpheres[0]; // 示例:选择第一个包围球作为目标
for (let i = 1; i < boundingSpheres.length; i++) {
if (boundingSpheres[i].radius > targetBoundingSphere.radius) {
targetBoundingSphere = boundingSpheres[i];
}
}
let cartographic = Cesium.Cartographic.fromCartesian(targetBoundingSphere.center);
let position = Cesium.Cartesian3.fromRadians(cartographic.longitude, cartographic.latitude,cartographic.height*10); // 可以根据需要调整高度
viewer.camera.flyTo({
destination: position,
orientation: {
heading: Cesium.Math.toRadians(0),
pitch: Cesium.Math.toRadians(-90),
roll: 0.0
}
});
} else {
console.warn("No bounding spheres available, using default camera position.");
// Fallback to default camera position or another strategy
}
},
setupClickListener() {
const handler = new Cesium.ScreenSpaceEventHandler(this.viewer.canvas);
let selectedFeature = null;
let selectedColor = null;
handler.setInputAction((click) => {
let ray = this.viewer.camera.getPickRay(click.position)
let cartesian = this.viewer.scene.globe.pick(ray, this.viewer.scene)
let pickedObject = this.viewer.scene.pick(click.position);
// const pickedObject = this.viewer.scene.pick(click.position);
console.log("pickedObject", pickedObject)
if (selectedFeature) {
selectedFeature.color = new Cesium.Color(1, 1, 1, 1); // 或者设置为初始颜色,如 Cesium.Color.WHITE
}
if (Cesium.defined(pickedObject) && pickedObject instanceof Cesium.Cesium3DTileFeature) {
const batchId = pickedObject.getProperty("batchId");
pickedObject.getPropertyNames().forEach(propertyName=>{
this.propertiesList[propertyName] = pickedObject.getProperty(propertyName)
})
console.log("this.propertiesList", this.propertiesList)
this.sendSelectPorperty(this.propertiesList)
if (batchId && batchId.indexOf("管线") !== -1) {
selectedFeature = pickedObject;
selectedColor = pickedObject.color
console.log("pickedObject.color", pickedObject.color)
pickedObject.color = Cesium.Color.MIDNIGHTBLUE;
} else if(batchId && batchId.indexOf("管点") !== -1){
selectedFeature = pickedObject;
selectedColor = pickedObject.color
console.log("pickedObject.color", pickedObject.color)
pickedObject.color = Cesium.Color.MIDNIGHTBLUE;
}
} else if(Cesium.defined(pickedObject) && pickedObject.entity){
this.selectedEntity = pickedObject.entity;
const id = pickedObject.id;
const name = pickedObject.name;
console.log(`拾取到的实体ID: ${id}, 名称: ${name}`);
}
}, Cesium.ScreenSpaceEventType.LEFT_CLICK);
},
},
</script>