learning_cesium/zengcheng.html

373 lines
17 KiB
HTML
Raw Permalink Normal View History

2024-03-19 18:06:25 +08:00
<!DOCTYPE html>
<html lang="en">
<head>
<!-- Use correct character set. -->
<meta charset="utf-8" />
<!-- Tell IE to use the latest, best version. -->
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<!-- Make the application on mobile take up the full browser screen and disable user scaling. -->
<meta
name="viewport"
content="width=device-width, initial-scale=1, maximum-scale=1, minimum-scale=1, user-scalable=no"
/>
<title>Learning Cesium!</title>
<script src="./Build/Cesium/Cesium.js"></script>
<style>
@import url(./Build/Cesium/Widgets/widgets.css);
html,
body,
#app,
#cesiumContainer {
width: 100%;
height: 100%;
margin: 0;
padding: 0;
overflow: hidden;
}
</style>
<!-- 引入样式 -->
<link rel="stylesheet" href="./js/elementui/index.css" />
<!-- import Vue before Element -->
<script src="./js/vue2710.js"></script>
<!-- import JavaScript -->
<script src="./js/elementui/index.js"></script>
<link rel="stylesheet" href="./js/moduel/Bubble.css" />
</head>
<body>
<div id="app">
<div id="cesiumContainer"></div>
</div>
<script type="module">
import viewUtil from "./js/moduel/viewUtil.js";
import Bubble from "./js/moduel/Bubble.js";
Cesium.Ion.defaultAccessToken =
"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJqdGkiOiI5ZjRjNTZkNC01NDYxLTRhMjQtOGEwZC1kZjA3YzQ5YTJlZDkiLCJpZCI6MjYwODQsInNjb3BlcyI6WyJhc3IiLCJnYyJdLCJpYXQiOjE1ODcxOTMwODN9.prGsSKyAW_9Ow5zHYPhbm3LsQL-ApQw5-5PNJkDaHi8";
new Vue({
el: "#app",
data: {},
methods: {
initViewer() {
// 添加 Mapbox tile provider
const mapboxAccess =
"pk.eyJ1IjoicWl1c2hpamllIiwiYSI6ImNsMDNvdDRybDEyc2YzZG9kbWZoY2FuOW0ifQ.4FH-BUupi46Z0zQ-CEm_Ig";
var customMapboxIamgery = new Cesium.MapboxStyleImageryProvider({
// url: "https://api.mapbox.com/styles/v1",
username: "qiushijie",
styleId: "clboooor3000714mi15y9j6ba",
accessToken: mapboxAccess,
scaleFactor: true,
});
var viewer = new Cesium.Viewer("cesiumContainer", {
geocoder: false, //位置查找
homeButton: false, //视图返回初始位置
sceneModePicker: false, //视角选择器
baseLayerPicker:false,//底图选择器
navigationHelpButton: false, //导航帮助按钮
animation: false, //动画控制器
creditContainer: document.createElement("div"),//版权显示
timeline: false, //时间线
fullscreenButton: false, //全屏控件
vrButton: false,
infoBox: false,
selectionIndicator: false,
imageryProvider:customMapboxIamgery
});
window.viewer = viewer;
var imageryLayers = viewer.scene.imageryLayers;
// //清除影像图层集合中的图层
imageryLayers.removeAll();
// var gaode = imageryLayers.addImageryProvider(new Cesium.UrlTemplateImageryProvider({
// // url : "GlobalTMS/satellite/{z}/{x}/{y}.jpg",
// url:"http://localhost:8078/zengcheng/tiles/{z}/{x}/{y}.png",
// // url:"http://localhost:8078/hubei/blue/{z}/{x}/{y}.png",
// fileExtension : "png",
// }));
imageryLayers.addImageryProvider(customMapboxIamgery);
// 添加统一的气泡弹窗实例
window.bubble = new Bubble({
viewer:viewer
});
// 调整整体的亮度
// var collection = viewer.scene.postProcessStages;
// var silhouette = collection.add(
// Cesium.PostProcessStageLibrary.createBrightnessStage()
// );
// silhouette.enabled = true;
// silhouette.uniforms.brightness = 0.7;
// 加载动态路网
this.rdSource = new Cesium.CustomDataSource("dynamicRoad");// 创建自定义数据源存放动态墙体的Entity
viewer.dataSources.add(this.rdSource);
let roadUrl = "http://127.0.0.1:8078/zengcheng/licheng_road.geojson"
fetch(roadUrl).then(res=>res.json()).then(result=>{
result.features.forEach(feature=>{
this.rdSource.entities.add(viewUtil.addDynamicLine(feature,"#fff",1))
})
console.log(result);
})
// 加载白模
let whiteUrl = "http://127.0.0.1:8078/zengcheng/3dtiles/licheng/tileset.json"
let whiteTileset = viewUtil.loadTileset(viewer,whiteUrl,0)
whiteTileset.readyPromise.then((tileset)=> {
this.move3dtilesMaxtrix(tileset);
tileset.style = new Cesium.Cesium3DTileStyle({
color: {
conditions: [['true', "color('rgba(255,255,255,0.9)')"]],
},
})
//实现渐变效果
tileset.tileVisible.addEventListener(function (tile) {
var content = tile.content;
var featuresLength = content.featuresLength;
for (let i = 0; i < featuresLength; i += 2) {
let feature = content.getFeature(i)
let model = feature.content._model
if (model && model._sourcePrograms && model._rendererResources) {
Object.keys(model._sourcePrograms).forEach(key => {
let program = model._sourcePrograms[key]
let fragmentShader = model._rendererResources.sourceShaders[program.fragmentShader];
let v_position = "";
if (fragmentShader.indexOf(" v_positionEC;") != -1) {
v_position = "v_positionEC";
} else if (fragmentShader.indexOf(" v_pos;") != -1) {
v_position = "v_pos";
}
const color = `vec4(${feature.color.toString()})`;
model._rendererResources.sourceShaders[program.fragmentShader] =
`
varying vec3 ${v_position};
void main(void){
vec4 position = czm_inverseModelView * vec4(${v_position},1); // 位置
gl_FragColor = ${color}; // 颜色
gl_FragColor *= vec4(vec3(position.z / 50.0), 1.0); // 渐变
// 动态光环
float time = fract(czm_frameNumber / 180.0);
time = abs(time - 0.5) * 2.0;
float glowRange = 260.0; // 光环的移动范围(高度)
float diff = step(0.005, abs( clamp(position.z / glowRange, 0.0, 1.0) - time));
gl_FragColor.rgb += gl_FragColor.rgb * (1.0 - diff);
}
`
})
model._shouldRegenerateShaders = true
}
}
});
// tileset.tileVisible.addEventListener(function(tile) {
// let content = tile.content;
// let featuresLength = content.featuresLength;
// let feature;
// for (var i = 0; i < featuresLength; i += 2) {
// feature = content.getFeature(i);
// let _model = feature.content._model;
// _model._shouldRegenerateShaders = true;
// // getOwnPropertyNames:返回指定对象的所有自身属性的属性名组成的数组
// // forEach对数组里的所有元素都执行一遍
// // Object.keys返回
// Object.getOwnPropertyNames(_model._sourcePrograms).forEach(function(j) {
// const _modelSourceP = _model._sourcePrograms[0];
// _model._rendererResources.sourceShaders[_modelSourceP.fragmentShader] =
// `
// varying vec3 v_positionEC;
// void main(void){
// vec4 position = czm_inverseModelView * vec4(v_positionEC,1); // 位置
// float glowRange = 100.0; // 光环的移动范围(高度)
// gl_FragColor = vec4(0.0, 0.3, 0.8, 0.8); // 颜色
// // 小于20米的低楼都不再变暗
// if(position.y > 5.0) {
// gl_FragColor *= vec4(vec3(position.y / 2.0), 0.8); // 渐变
// }else {
// gl_FragColor *= vec4(vec3(position.y / 10.0), 0.8); // 渐变
// }
// // 动态光环
// float time = fract(czm_frameNumber / 360.0);
// time = abs(time - 0.5) * 3.0;
// float diff = step(0.005, abs( clamp(position.y / glowRange, 0.0, 1.0) - time));
// gl_FragColor.rgb += gl_FragColor.rgb * (1.0 - diff);
// }
// `
// // ` varying vec3 v_positionEC;
// // void main(void){
// // vec4 position = czm_inverseModelView * vec4(v_positionEC,1); // 位置
// // float glowRange = 100.0; // 光环的移动范围(高度)
// // gl_FragColor = vec4(0.2, 0.5, 1.0, 1.0); // 颜色
// // // 底楼 亮度太暗了那么把20%以内的底楼,都不再变暗
// // if((position.z / 1.0) < 0.2) {
// // gl_FragColor *= vec4(vec3(position.z / 100.0 * 2.0), 1.0);
// // }else{
// // gl_FragColor *= vec4(vec3(position.z / 100.0), 1.0); // 渐变
// // }
// // // 动态光环
// // float time = fract(czm_frameNumber / 360.0);
// // time = abs(time - 0.5) * 2.0;
// // float diff = step(0.005, abs( clamp(position.y / glowRange, 0.0, 1.0) - time));
// // gl_FragColor.rgb += gl_FragColor.rgb * (1.0 - diff);
// // }`
// })
// _model._shouldRegenerateShaders = true;
// }
// })
})
// 加水纹
this.riverPrimitives = viewer.scene.primitives.add(// 创建primitive集合存储水系图元对象
new Cesium.PrimitiveCollection()
);
let waterUrl = "http://127.0.0.1:8078/zengcheng/licheng_water.geojson"
fetch(waterUrl).then(res=>res.json()).then(result=>{
result.features.forEach(feature=>{
viewUtil.addWaterFeature1(this.riverPrimitives,feature);
})
})
viewer.camera.setView({
// destination : Cesium.Cartesian3.fromDegrees(113.9044,23.3215,1000000),
destination: new Cesium.Cartesian3(-2368517.8753985167, 5368259.496963671, 2498952.3392142765),
orientation: {
heading :0.21256304726696484, //Cesium.Math.toRadians(0.0), // east, default value is 0.0 (north)
pitch :-0.3255554838380681, //Cesium.Math.toRadians(-90), // default value (looking down)
roll : 0.0000316945339733 // default value
}
});
this.initEvent();
},
move3dtilesMaxtrix(tileset) {
// xyz 笛卡尔 lat lon 弧度 【 lat lon 经纬度 】
// 根据tileset的边界球体中心点的笛卡尔坐标得到经纬度坐标
const cartographic = Cesium.Cartographic.fromCartesian(
tileset.boundingSphere.center
)
// 根据经纬度和高度0得到地面笛卡尔坐标
const surface = Cesium.Cartesian3.fromRadians(
cartographic.longitude,
cartographic.latitude,
0 // cartographic.height
)
// 根据经纬度和需要的高度,得到偏移后的笛卡尔坐标
const offset = Cesium.Cartesian3.fromRadians(
cartographic.longitude, // + Cesium.Math.toRadians(0.0001), 这里更改的是经纬度偏移
cartographic.latitude,
0 // 程度的高度 需要偏移 下降500米
)
// offset.x += 100 // 这里可以更改 真实 米的偏移
// const offset = Cesium.Cartesian3.fromDegrees(
// tileset.boundingSphere.center.x + 10,
// tileset.boundingSphere.center.y,
// 0.0
// )
// 计算坐标变换,得到新的笛卡尔坐标
const translation = Cesium.Cartesian3.subtract(
offset,
surface,
new Cesium.Cartesian3()
)
// 调整3dtiles位置
tileset.modelMatrix = Cesium.Matrix4.fromTranslation(translation)
},
initEvent(){
let handler = new Cesium.ScreenSpaceEventHandler(viewer.scene.canvas);
let vm = this;
handler.setInputAction(function (evt) {
// 获取该位置的所有primitive集合
let picks = viewer.scene.drillPick(evt.position);
viewer.scene.render();
let isOn3dtiles = false;
let pickPrimitive = [];
let pickEntity =[];
let pickTileFeature =[];
for (var i = 0; i < picks.length; i++) {
if (picks[i] && picks[i] instanceof Cesium.Cesium3DTileFeature) {
//模型上拾取
isOn3dtiles = true;
pickTileFeature.push(picks[i]);
}
if(picks[i].primitive && picks[i].primitive instanceof Cesium.GroundPrimitive){
pickPrimitive.push(picks[i])
}
if(picks[i].id instanceof Cesium.Entity){
pickEntity.push(picks[i].id)
}
}
if(window.selectPrimitive){
// viewer.scene.primitives.remove(window.selectPrimitive);
// window.selectPrimitive=null;
let comp = window.selectPrimitive;
let attr = comp.primitive.getGeometryInstanceAttributes(comp.id);
attr.color = Cesium.ColorGeometryInstanceAttribute.toValue(Cesium.Color.fromBytes(comp.color[0],comp.color[1],comp.color[2],comp.color[3]));
window.selectPrimitive=null;
}
let currCartesian3 = viewer.scene.globe.pick(viewer.camera.getPickRay(evt.position),viewer.scene)
if (pickPrimitive.length>0||pickEntity.length>0) {
// 设置选中高亮primitive
if(pickPrimitive.length&&pickPrimitive[0].id){
var attributes = pickPrimitive[0].primitive.getGeometryInstanceAttributes(pickPrimitive[0].id);
window.selectPrimitive = {
id:pickPrimitive[0].id,
primitive:pickPrimitive[0].primitive,
color:{...attributes.color}
}
attributes.color = Cesium.ColorGeometryInstanceAttribute.toValue(Cesium.Color.fromRandom({
alpha: 0.5
}));
}
//坐标转换
// let currCartesian3 = viewer.scene.pickPosition(evt.position);
// let pickobject = viewer.scene.pick(evt.position); //取最上面的primitive对象
let fields = {};
if (pickEntity.length) {
fields = JSON.parse(pickEntity[0].id);
}else if(pickPrimitive.length){
fields = pickPrimitive[0].id;
}
window.bubble.clearDiv()
window.bubble.addDynamicLabel(fields,currCartesian3)
} else if(pickTileFeature.length){
let fields = {};
const feature = pickTileFeature[0];
const propertyNames = feature.getPropertyNames();
const length = propertyNames.length;
for (let i = 0; i < length; ++i) {
const propertyName = propertyNames[i];
if(propertyName == "采集时间"){
fields["测试的时间"] = feature.getProperty(propertyName);
}else{
fields[propertyName] = feature.getProperty(propertyName);
}
}
window.bubble.clearDiv()
window.bubble.addDynamicLabel(fields,currCartesian3)
}
}, Cesium.ScreenSpaceEventType.LEFT_CLICK);
}
},
mounted() {
this.initViewer();
},
});
</script>
</body>
</html>