- 加载地形数据,通过经纬度获取地形高度
viewer.terrainProvider = new Cesium.CesiumTerrainProvider({
url:""
})
Cesium.createWorldTerrain()
requestWaterMask : true,
requestVertexNormals : true
viewer.scene.globe.enableLighting = true;
// 获取地形高度
let promise = Cesium.sampleTerrainMostDetailed(terrain, positions);
// 根据切片层级 获取
const promise = Cesium.sampleTerrain(terrainProvider, 11, positions);
Cesium.Cartographic.fromDegrees()
imageProveder
//http://shangetu{s}.map.bdimg.com/it/u=x={x};y={y};z={z};v=009;type=sate&fm=46 //影像数据
//http://online{s}.map.bdimg.com/onlinelabel/?qt=tile&x={x}&y={y}&z={z}&styles=pl&scaler=1&p=1 //矢量切片
//http://online{s}.map.bdimg.com/tile/?qt=tile&x={x}&y={y}&z={z}&styles={sh/sl}&v=020 //标注
// http://api0.map.bdimg.com/customimage/tile?&x={x}&y={y}&z={z}&scale=1&customid=dark //风格地图 dark,midnight,grayscale,hardedge,light,redalert,googlelite,grassgreen,pink,darkgreen,bluish
//
imageryProvider : new BaiduImageryProvider({
url: "http://api0.map.bdimg.com/customimage/tile?&x={x}&y={y}&z={z}&scale=1&customid=googlelite"
})
加载geojson数据
var promise = Cesium.GeoJsonDataSource.load('./data/hbeiprovince.json');
promise.then(datasource=>{
viewer.dataSources.add(datasource);
datasource.entities.values.forEach(enetity=>{
console.log(enetity);
enetity.polygon.outlineColor=Cesium.Color.RED;
enetity.polygon.material=Cesium.Color.BLUE;
enetity.polygon.height=1000;
enetity.polygon.extrudedHeight=2000;
})
viewer.zoomTo(datasource)
})
// 申明一个XMLHttpRequest
var request = new XMLHttpRequest();
// 设置请求方法与路径
request.open("get", './data/hbeiprovince.json');
// 不发送数据到服务器
request.send(null);
//XHR对象获取到返回信息后执行
request.onload = function () {
// 解析获取到的数据
var data = JSON.parse(request.responseText);
data.features.forEach(feature=>{
feature.geometry.coordinates.forEach(coordinate=>{
console.log(coordinate);
viewer.entities.add({
name:"hbei",
polygon:{
hierarchy:{
positions:Cesium.Cartesian3.fromDegreesArray(coordinate.flat())
},
height:10000,
extrudedHeight:20000,
material:Cesium.Color.RED,
outline:true,
outlineColor:Cesium.Color.ORANGE
}
})
})
})
}
鼠标事件
var handler = new Cesium.ScreenSpaceEventHandler(viewer.scene.canvas);
handler.setInputAction(function(click){
console.log('左键单击事件:',click.position);
},Cesium.ScreenSpaceEventType.LEFT_CLICK);
handler.setInputAction(function(click){
console.log('左键双击事件:',click.position);
},Cesium.ScreenSpaceEventType.LEFT_DOUBLE_CLICK);
handler.setInputAction(function(click){
console.log('左键按下事件:',click.position);
},Cesium.ScreenSpaceEventType.LEFT_DOWN);
handler.setInputAction(function(click){
console.log('左键弹起事件:',click.position);
},Cesium.ScreenSpaceEventType.LEFT_UP);
handler.setInputAction(function(click){
console.log('中键按下事件:',click.position);
},Cesium.ScreenSpaceEventType.MIDDLE_DOWN);
handler.setInputAction(function(click){
console.log('中键弹起事件:',click.position);
},Cesium.ScreenSpaceEventType.MIDDLE_UP);
handler.setInputAction(function(movement){
console.log('移动事件:',movement.endPosition);
},Cesium.ScreenSpaceEventType.MOUSE_MOVE);
handler.setInputAction(function(click){
console.log('右键单击事件',click.position);
},Cesium.ScreenSpaceEventType.RIGHT_CLICK);
handler.setInputAction(function(click){
console.log('右键按下事件',click.position);
},Cesium.ScreenSpaceEventType.RIGHT_DOWN);
handler.setInputAction(function(click){
console.log('右键弹起事件',click.position);
},Cesium.ScreenSpaceEventType.RIGHT_UP);
handler.setInputAction(function(wheelment){
console.log('滚轮事件:',wheelment);
},Cesium.ScreenSpaceEventType.WHEEL);
handler.removeInputAction(Cesium.ScreenSpaceEventType.LEFT_CLICK);
var ray = this.viewer.camera.getPickRay(movement.position);
var position = this.viewer.scene.globe.pick(ray, this.viewer.scene);
var cartographic = Cesium.Ellipsoid.WGS84.cartesianToCartographic(position);
倾斜摄影数据
var tileset = new Cesium.Cesium3DTileset({url: "./test3dtiles/tileset.json", maximumScreenSpaceError:1, });
viewer.scene.primitives.add(tileset);
viewer.zoomTo(tileset)
callbackProperty
- CallbackProperty就是属性回调函数,对于实体来说,比如一条线,如果我想改变其线宽,或者改变其颜色,但又不想重新绘制,那CallbackProperty就派上了用场。 请看如下示例:
let viewer = new Cesium.Viewer('cesiumContainer');
let entity = viewer.entities.add({
polyline: {
positions: new Cesium.CallbackProperty(changePosition, false),
width: new Cesium.CallbackProperty(changeWidth, false),
material: new Cesium.ColorMaterialProperty(new Cesium.CallbackProperty(changeColor, false)),
}
});
function changePosition(time, isConstant) {
let lat = 20;
let lon = 100;
return Cesium.Cartesian3.fromDegreesArray(
[lon, lat, lon - Math.floor(Math.random() * 1000), lat - Math.floor(Math.random() * 100)],
Cesium.Ellipsoid.WGS84,
isConstant
);
}
function changeWidth(time, isConstant) {
return Math.floor(Math.random() * 10);
}
function changeColor(time, isConstant) {
return Cesium.Color.fromRandom({
minimumRed: 0.1,
minimumGreen: 0.1,
minimumBlue: 0.1,
alpha: 1.0
});
}
<script type="text/javascript">
var viewer = new Cesium.Viewer("cesiumcontainer", {
//搜索框
geocoder: false,
//home键
homeButton: false,
// 动画控件
animation: false,
//全屏按钮
fullscreenButton: false,
//场景模式选择器
sceneModePicker: false,
//时间轴
timeline: false,
//导航提示
navigationHelpButton: false,
//地图选择器
baseLayerPicker: false,
imageryProvider: new Cesium.UrlTemplateImageryProvider({
url: "http://webrd01.is.autonavi.com/appmaptile?&scale=1&lang=zh_cn&style=8&x={x}&y={y}&z={z}",
minimumLevel: 1,
maximumLevel: 18
}),
})
// console.log(Cesium.Cartographic);
var handler = new Cesium.ScreenSpaceEventHandler(viewer.scene.canvas);
handler.setInputAction(function (movement) {
var ray = this.viewer.camera.getPickRay(movement.position);
if (!ray) return null;
var position = this.viewer.scene.globe.pick(ray, this.viewer.scene);
console.log(movement.position);
console.log(position);
var cartographic = Cesium.Ellipsoid.WGS84.cartesianToCartographic(position);
console.log(cartographic);
var lon = Cesium.Math.toDegrees(cartographic.longitude);
var lat = Cesium.Math.toDegrees(cartographic.latitude);
console.log(lon, lat);
}, Cesium.ScreenSpaceEventType.LEFT_CLICK);
//创建DataSource
var datasource = new Cesium.CustomDataSource("enetiestestdata");
viewer.dataSources.add(datasource)
var exheight=10000;
var color1= Cesium.Color.BLUE;
//添加点
datasource.entities.add({
id: 'polygontest',
name: 'Wyoming',
polygon: {
hierarchy: Cesium.Cartesian3.fromDegreesArray([
109.080842, 45.002073,
105.91517, 45.002073,
104.058488, 44.996596,
104.053011, 43.002989,
104.053011, 41.003906,
105.728954, 40.998429,
107.919731, 41.003906,
109.04798, 40.998429,
111.047063, 40.998429,
111.047063, 42.000709,
111.047063, 44.476286,
111.05254, 45.002073,
109.080842, 45.002073]),
height: 100,
extrudedHeight:new Cesium.CallbackProperty(()=>{return exheight},false),
material:new Cesium.ColorMaterialProperty(new Cesium.CallbackProperty(changecolor,false)),
outline: true,
outlineColor:Cesium.Color.BLUE,
outlineWidth:1,
fill: true
}
});
function changecolor(){
return new Cesium.Color(Math.random(),Math.random(),Math.random())
}
viewer.zoomTo(datasource)
// viewer.entities.removeById("polylinetest");
// tempentity=null;
window.setInterval(()=>{exheight+=100},100)
</script>
加载gltf
- glTF文件介绍
glTF
(Graphics Library Transmission Format)
是一种用于存储3D模型和场景的格式。它是一种开放的标准格式,可用于在不同的3D引擎和软件之间传输和交换3D模型和场景数据。glTF文件包含了设计场景或模型的几何形状、材质、纹理、动画等信息,同时有很好的兼容性和可扩展性。glTF文件基于JSON格式,具有易于阅读和修改的特点,同时也易于使用编程语言进行解析和使用。
glTF支持两种文件格式:
*.glTF和 *.glb
。.glTF是一个基于JSON格式的文本文件,它可以包含场景、节点、网格信息、材质、动画、相机等3D模型元素,并且可以包括外部资源,如纹理、图像和二进制数据等。
.glTF
文件易于阅读、修改和编辑,同时可以使用gzip进行压缩以减小文件大小。但是.glTF
文件格式在处理复杂场景时,可能会变得比较冗长,处理速度较慢。.glb
是一种基于二进制的文件格式,它包含所有的glTF数据,包括所有的外部资源。由于.glb
文件是二进制文件,大大减小了文件大小和加载时间,同时保持了.glTF
文件的灵活性和可编辑性。.glb
文件也可以使用gzip压缩以进一步减小文件大小。但是.glb
文件格式作为二进制文件,难以直接进行编辑和修改。
Cesium中的模型坐标系
在Cesium中,为了确保各种数据都可以在三维场景中正确地显示和交互,定义了一个特定的模型坐标系,即ENU坐标系,其中ENU代表东北上。
- 东(East):X轴朝向地球表面东方,单位为米。
- 北(North):Y轴朝向地球表面北方,单位为米。
- 上(Up):Z轴朝向地心,在ENU坐标系中通常是指垂直于地球表面的向上方向,单位为米。
<div id="cesiumcontainer" style="width:100%;height:100%"></div>
<script type="text/javascript">
var viewer = new Cesium.Viewer("cesiumcontainer", {
//搜索框
geocoder: false,
//home键
homeButton: false,
// 动画控件
animation: false,
//全屏按钮
fullscreenButton: false,
//场景模式选择器
sceneModePicker: false,
//时间轴
timeline: false,
//导航提示
navigationHelpButton: false,
//地图选择器
baseLayerPicker: false,
//动态动画
shouldAnimate: true,
imageryProvider: new Cesium.UrlTemplateImageryProvider({
url: "http://webrd01.is.autonavi.com/appmaptile?&scale=1&lang=zh_cn&style=8&x={x}&y={y}&z={z}",
minimumLevel: 1,
maximumLevel: 18
}),
})
//开启阴影
viewer.shadows = true,
viewer.scene.globe.enableLighting = true
//显示帧率
viewer.scene.debugShowFramesPerSecond = true
// console.log(Cesium.Cartographic);
let position = Cesium.Cartesian3.fromDegrees(109, 34, 2);
// 设置模型方向
let hpRoll = new Cesium.HeadingPitchRoll(Cesium.Math.toRadians(-90), Cesium.Math.toRadians(30), Cesium.Math.toRadians(30));//弧度
let orientation = Cesium.Transforms.headingPitchRollQuaternion(position, hpRoll);
let model = viewer.entities.add({
// 模型id
id: 'model',
// 模型位置
position: position,
// 模型方向
orientation: orientation,
// 模型资源
model: {
minimumPixelSize: 128,
// 模型路径
uri: './data/Cesium_Air.glb',
// colorBlendMode:Cesium.ColorBlendMode.REPLACE,
// color:Cesium.Color.RED,
//轮廓
shadows: Cesium.ShadowMode.ENABLED,
// silhouetteColor:Cesium.Color.BLUE,
// silhouetteSize:5,
// distanceDisplayCondition:new Cesium.DistanceDisplayCondition(100, 20000),
}
})
viewer.zoomTo(model)
</script>
加载本地地图
var viewer = new Cesium.Viewer("cesiumcontainer", {
//搜索框
geocoder: false,
//home键
homeButton: false,
// 动画控件
animation: false,
//全屏按钮
fullscreenButton: false,
//场景模式选择器
sceneModePicker: false,
//时间轴
timeline: false,
//导航提示
navigationHelpButton: false,
//地图选择器
baseLayerPicker: false,
//动态动画
shouldAnimate: true,
imageryProvider: new Cesium.UrlTemplateImageryProvider({
url: "./tianditu/{z}/{x}/{y}.png",
minimumLevel: 0,
maximumLevel: 11
}),
})
// 114.32-114.524-36.927-37.22
viewer.imageryLayers.addImageryProvider(new Cesium.UrlTemplateImageryProvider({
url: "./notes/{z}/{x}/{y}.png",
// 最大,最小层级
minimumLevel: 0,
maximumLevel: 11,
// 范围
rectangle:new Cesium.Rectangle(Cesium.Math.toRadians(114.32), Cesium.Math.toRadians(36.927),
Cesium.Math.toRadians(114.524), Cesium.Math.toRadians(37.22))
}))
<template>
<div id="cesiumContainer"></div>
</template>
<script setup>
import * as Cesium from 'cesium'
import { onMounted } from 'vue';
// import modelFile from '/feiji.glb'
let viewer, imageLayers
onMounted(async () => {
// 初始化Cesium
initViewer()
// 加载影像数据
addImageLayers()
// 加载gltf数据
addGLTFModel('/feiji.glb', 4000)
})
function initViewer() {
viewer = new Cesium.Viewer('cesiumContainer', {
animation: false,//动画小部件
baseLayerPicker: false,//地图图层组件
fullscreenButton: false,//全屏组件
geocoder: false,//地理编码搜索组件
homeButton: false,//首页组件
infoBox: false,//信息框
sceneModePicker: false,//场景模式
selectionIndicator: false,//选取指示器组件
timeline: false,//时间轴
navigationHelpButton: false,//帮助按钮
navigationInstructionsInitiallyVisible: false,
})
// console.log(viewer);
// 隐藏logo信息
viewer._cesiumWidget._creditContainer.style.display = 'none'
// 隐藏地球
// viewer.scene.globe.show = false
imageLayers = viewer.imageryLayers
viewer.scene.globe.depthTestAgainstTerrain = true;// 随着地图缩放深度增加会导致数据获取不到,所以需要进行开启深度监测
// console.log(imageLayers);
}
async function addImageLayers() {
imageLayers.remove(imageLayers.get(0)) //清楚Cesium默认加载的影像地图数据(默认是加载的bing地图)
// Bing地图
const bing = await Cesium.BingMapsImageryProvider.fromUrl(
"https://dev.virtualearth.net", {
key: "AodxPjHCueIzbuOPovDaDba7D6qpNMPdJ8nt96KsDjKIs0yz5j4jTuNMdMdO6tJZ",
mapStyle: Cesium.BingMapsStyle.AERIAL//可选参数,指定地图样式
})
imageLayers.addImageryProvider(bing)
}
async function addGLTFModel(url, height) {
// Entity方法加载gltf
viewer.entities.removeAll() //加载之前先清楚所有entity
const position = Cesium.Cartesian3.fromDegrees(-123.0744619, 44.0503706, height)
const heading = Cesium.Math.toRadians(135) //135度转弧度
const pitch = Cesium.Math.toRadians(0);
const roll = 0
const hpr = new Cesium.HeadingPitchRoll(heading, pitch, roll)
const orientation = Cesium.Transforms.headingPitchRollQuaternion(
position,
hpr
)
const entity = await viewer.entities.add({
name: 'feiji',
position: position,
orientation: orientation,
model: {
uri: url,//注意entitits.add方式加载gltf文件时,这里是uri,不是url,并且这种方式只能加载.glb格式的文件
scale: 1.0,//缩放比例
minimumPixelSize: 128,//最小像素大小,可以避免太小看不见
maximumScale: 20000,//模型的最大比例尺大小。minimumPixelSize的上限
incrementallyLoadTextures: true,//加载模型后纹理是否可以继续流入
runAnimations: true,//是否启动模型中制定的gltf动画
clampAnimations: true,//制定gltf动画是否在没有关键帧的持续时间内保持最后一个姿势
shadows: Cesium.ShadowMode.ENABLED,
heightReference: Cesium.HeightReference.NONE
}
})
viewer.trackedEntity = entity; // 聚焦模型
viewer.zoomTo(entity)
}
</script>
<style scoped></style>
material 材质
<script type="text/javascript">
var viewer = new Cesium.Viewer("cesiumcontainer", {
//搜索框
geocoder: false,
//home键
homeButton: false,
// 动画控件
animation: false,
//全屏按钮
fullscreenButton: false,
//场景模式选择器
sceneModePicker: false,
//时间轴
timeline: false,
//导航提示
navigationHelpButton: false,
//地图选择器
baseLayerPicker: false,
imageryProvider: new Cesium.UrlTemplateImageryProvider({
url: "http://webrd01.is.autonavi.com/appmaptile?&scale=1&lang=zh_cn&style=8&x={x}&y={y}&z={z}",
minimumLevel: 1,
maximumLevel: 18
}),
})
// console.log(Cesium.Cartographic);
//创建DataSource
var datasource = new Cesium.CustomDataSource("enetiestestdata");
viewer.dataSources.add(datasource)
//添加点
var pos =[[116.38059,39.871148],[116.399097,39.872205],[116.397612,39.898675],[116.396086,39.89944],[116.395563,39.907995],[116.392259,39.907881],[116.392175,39.92242],[116.399474,39.923574],[116.396692,39.928306],[116.396169,39.94006],[116.394266,39.940629],[116.393346,39.957355],[116.38678,39.957014],[116.387658,39.96093],[116.389498,39.96314],[116.40788,39.962182],[116.407504,39.973995],[116.411101,39.97146],[116.411415,39.964928],[116.414196,39.962182],[116.424861,39.962279],[116.429002,39.957274],[116.429483,39.950155],[116.436698,39.949245],[116.435422,39.952121],[116.442239,39.9497],[116.440566,39.945295],[116.446338,39.946205],[116.443703,39.936663],[116.443682,39.928664],[116.434314,39.92868],[116.434983,39.913964],[116.436488,39.902042],[116.448722,39.903246],[116.446819,39.900042],[116.447154,39.894186],[116.450876,39.894088],[116.450939,39.890249],[116.444059,39.890038],[116.445648,39.879283],[116.44364,39.87284],[116.442574,39.87188],[116.423209,39.872824],[116.413652,39.871148],[116.41589,39.863645],[116.41246,39.858942],[116.406856,39.859967],[116.3955,39.858682],[116.394956,39.862734],[116.387888,39.867372],[116.380632,39.866054],[116.38059,39.871148]]
var entity= datasource.entities.add({
id: 'polygontest',
name: 'Wyoming',
polygon: {
hierarchy: Cesium.Cartesian3.fromDegreesArray(pos.flat()),
height: 100,
material: new Cesium.ImageMaterialProperty({
image:'./images/tengxuntouxiang.png',
repeat:new Cesium.Cartesian2(10,10),
color:Cesium.Color.RED,
transparent:true,
}),
outline: true,
outlineColor: Cesium.Color.BLUE,
outlineWidth: 1,
fill: true
}
});
viewer.zoomTo(entity)
</script>
发光线
const cesiumContainer = ref();
onMounted(async () => {
if (cesiumContainer) {
viewer = new Cesium.Viewer(cesiumContainer.value, {
timeline: true, // 时间轴
animation: true, // 动画控件
});
viewer.scene.debugShowFramesPerSecond = true
//创建DataSource
var datasource = new Cesium.CustomDataSource("enetiestestdata");
viewer.dataSources.add(datasource)
//添加点
var entity = viewer.entities.add({
id: "polylinetest",
name: 'boderLine',
polyline: {
positions: Cesium.Cartesian3.fromDegreesArray([88, 39, 109, 39]),
width: 20,
material: new Cesium.PolylineArrowMaterialProperty(Cesium.Color.RED)
},
})
entity = viewer.entities.add({
id: "polylinetest1",
name: 'boderLine',
polyline: {
positions: Cesium.Cartesian3.fromDegreesArray([88, 35, 109, 35]),
width: 20,
material: new Cesium.PolylineDashMaterialProperty({
color: Cesium.Color.BLUE,
// gapColor:Cesium.Color.RED,
dashLength: 50,
dashPattern: 120
})
},
})
entity = viewer.entities.add({
id: "polylinetest2",
name: 'boderLine',
polyline: {
positions: Cesium.Cartesian3.fromDegreesArray([138, 30, 159, 30]),
width: 20,
material: new Cesium.PolylineGlowMaterialProperty({
color: Cesium.Color.BLUE,
glowPower: 0.9,
taperPower: 0.5
})
},
})
viewer.zoomTo(entity)
}
})
return {
cesiumContainer
}
}