Cesium视角切换、定位、读取文件,构建数据源,实体控制,模型控制等

本文详细介绍了Cesium中viewer和camera类的飞行定位方法,包括飞行动画、视角锁定、相机操作以及根据范围计算经纬度等功能。同时,展示了如何读取和处理JSON数据,以及通过GeoJsonDataSource加载数据源。此外,还涵盖了数据源的创建、清除、显示隐藏及模型的样式控制等操作。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

飞行定位方法

viewer类
viewer.flyTo(target, options) 有飞行动画效果,pitch非默认值时推荐使用
viewer.zoomTo(target, options) 直接定位至目标点
viewer.trackedEntity = entity 视角会锁定到设定目标实体
可通过viewer.trackedEntity = undefined 取消视角锁定
camera类
viewer.camera.flyTo(options) 有飞行动画效果
viewer.camera.flyToBoundingSphere(boundingSphere, options) 有飞行动画效果
viewer.camera.setView(options)
viewer.camera.lookAt(target, offset) 视角会锁定到设定目标位置
viewer.camera.lookAtTransform(transform, offset) 常用于四维矩阵定位
可通过viewer.camera.lookAtTransform(Matrix4.IDENTITY)取消lookAt视角锁定
viewer.camera.twistLeft(cMath.PI_OVER_SIX) 弧度制,相机逆时针旋转一定角度
viewer.camera.twistRight(cMath.PI_OVER_SIX) 弧度制,相机顺时针旋转一定角度
viewer.camera.zoomIn(5000) 相机放大一定距离
viewer.camera.zoomOut(5000) 相机缩小一定距离
viewer.camera.move(direction, amount) 相机沿指定方向移动一定距离
viewer.camera.moveForward(5000) 相机向后一定距离
viewer.camera.moveBackward(5000) 相机向前一定距离
viewer.camera.moveUp(5000) 相机向上移动一定距离
viewer.camera.moveDown(5000) 相机向下移动一定距离
viewer.camera.moveLeft(5000) 相机向左移动一定距离
viewer.camera.moveRight(5000) 相机向右移动一定距离
位置参数
pitch:俯仰角,默认-90(弧度)—— 前后空翻
heading:偏航角,默认0(弧度)—— 左右方向
roll:翻滚角,默认0(弧度)—— 侧空翻
range:范围(米)—— 距离目标的距离

飞至视角

		//知道经纬度的情况下
	    /* viewer.camera.flyTo({
	         destination : Cesium.Cartesian3.fromDegrees(116.523753404617, 40.2340042591095, 1000.0),
	         orientation: {"pitch":-0.5450456670292048,"heading":0.018399360640374063,"roll":0.0018415377068681238}
	     });*/
	     //知道笛卡尔的情况下
	    viewer.camera.flyTo(
	        {
	            "destination": {"x": -2177577.305512763, "y": 4362932.485127032, "z": 4098026.456405151},
	            "orientation":{"pitch": -1.4864402773467176, "heading": 4.747122814066271, "roll": 6.243888148462918}
	        });

		//飞至全球
		viewer.camera.flyTo({
		   destination: Cesium.Rectangle.fromDegrees(30, 0, 180, 60),
		   complete: () => {
		       //加载其他数据
		   },
		});

根据范围计算经纬度

/***
 * 根据范围飞行
 * @param {*}  data = [
				[116.52453466251528, 40.233651754887056, 1],
                [116.52453466251528, 40.233471232847634, 1],
                [116.524521776882, 40.233471232847634, 1],
                [116.524521776882, 40.233651754887056, 1]
           ]
 */
getExtent(data) {
    return new Promise(function (resolve) {
        var xmin, xmax, ymin, ymax;
        data.forEach(i => {
            if (!xmin && !xmax && !ymin && !ymax) {
                xmin = Number(i[0]);
                xmax = Number(i[0]);
                ymin = Number(i[1]);
                ymax = Number(i[1]);
            } else {
                if (xmin > Number(i[0])) {
                    xmin = Number(i[0]);
                }
                if (xmax < Number(i[0])) {
                    xmax = Number(i[0]);
                }
                if (ymin > Number(i[1])) {
                    ymin = Number(i[1]);
                }
                if (ymax < Number(i[1])) {
                    ymax = Number(i[1]);
                }
            }
        });
        if (!xmin && !xmax && !ymin && !ymax) {
            resolve();
        } else {
            resolve({
                xmin: xmin,
                ymin: ymin,
                xmax: xmax,
                ymax: ymax
            });
        }
    });
}

根据范围计算结果飞行

/***
 * 根据范围数据构造新的实体飞行
 * @param {*}  data = {
	xmin: 116.52453466251528,
	ymin: 40.233651754887056,
	xmax: 116.52453476251528,
	ymax: 40.233651764887056
}
 */
flyToExtent(data) {
    let viewer = getViewer();
    //构造新的实体,透明度为0
    let loactionTectEntity = viewer.entities.add({
        rectangle: {
            coordinates: Cesium.Rectangle.fromDegrees(
                data.xmin,
                data.ymin,
                data.xmax,
                data.ymax
            ),
            material: Cesium.Color.GREEN.withAlpha(0),
            height: 1,
            outline: false,
        },
    });
    let pro = viewer.flyTo(loactionTectEntity, {
        duration: 3,
        offset: new Cesium.HeadingPitchRange( Cesium.Math.toRadians(45),  Cesium.Math.toRadians(-35.0),200)
    });
    pro.then(() => )
    	//移除新的实体
        viewer.entities.remove(loactionTectEntity);
    });
}

读取json数据

/**
 * json文件读取
 * @param {*} url json的地址
 */
jsonParse(url) {
    return new Promise((resolve, reject) => {
        let features = null;
        Cesium.Resource.fetchJson({
            url: url,
        }).then((val) => {
            if (val.features && val.features.length > 0) {
                features = val.features;
            }
            resolve(features);
        });
    });
}

通过geojson数据获取数据源

/**
 * json文件读取
 * @param {*} url json的地址
 */
jsonToDataSource(url) {
	return new Promise((resolve, reject) => {
		Cesium.GeoJsonDataSource.load(url, {
	        clampToGround: true,
	      }).then(datasource => {
	        resolve(datasource );
	    });    
    });   
}

构造数据源

/**
 * Cesium中数据源构造通用方法
 * @param {*} datasouceName:实体名称
 * --------------------------------------------------------------------------------------------
 */
map_common_addDatasouce(datasouceName) {
    let datasouce = getViewer().dataSources._dataSources.find(t => {
        return t && t.name == datasouceName;
    });
    if (!datasouce) {
        datasouce = new Cesium.CustomDataSource(datasouceName);
        getViewer().dataSources.add(datasouce);
    }
    return datasouce;
}

读取json数据加载实体

jsonParse("/json/home/北京市.json").then((val) => {
        if (val && val.length > 0) {
            val.forEach((el) => {
            	//通过CustomDataSource构造数据源
            	let datasource = map_common_addDatasouce(datasourceName.BEIJING_LINE);
                datasource.entities.add(new Entity({
                    //Entity实体
                    /*polygon: {
	                        hierarchy: Cesium.Cartesian3.fromDegreesArray(positions),
	                        material: Cesium.Color.fromRandom()
	                  }*/
                }))
                //通过entities实体
                /*getViewer().entities.add(
			        new Entity({
			            //Entity实体
			            /*polygon: {
	                        hierarchy: Cesium.Cartesian3.fromDegreesArray(positions),
	                        material: Cesium.Color.fromRandom()
	                    }*/
			        })
			    );*/
            })  
        }
    })

通过GeoJsonDataSource获取数据源加载实体

jsonToDataSource("/json/home/北京市.json").then((datasource)=>{
        getViewer().dataSources.add(datasource);
        let entities = datasource.entities.values;
        for (let index = 0; index < entities.length; index++) {
            const entity = entities[index];
            if (entity.polygon) {
            	//Entity实体样式
                //entity.polygon.material = Cesium.Color.fromRandom();
            }
        }
    })

清除实体

/**
 * @param {*} datasouceName:实体名称
 * --------------------------------------------------------------------------------------------
 */
datasouceIsRemove(datasouceName) {
    let datasouce = map_common_addDatasouce(datasouceName);
    if (datasouce !== null || datasouce !== undefined) {
       datasouce.entities.removeAll();
    }
}

控制实体显隐

/**
 * 控制datasouceName显示隐藏
 * @param {*} datasouceName:实体名称
 * --------------------------------------------------------------------------------------------
 */
datasouceIsShow(datasouceName, isShow, id = '') {
	let datasouce = map_common_addDatasouce(datasouceName);
    if (datasouce !== null || datasouce !== undefined) {
        if (!!id) {//控制某个实体
            let obj = datasouce.entities.values.find(item => item.properties.details._value.id === id);
            if (obj) {
                obj.show = isShow
            }
        } else {//控制某类型实体
            datasouce.entities.values.forEach(item=>{
                item.show = isShow
            })
        }
    }
}

清除模型

/**
 * @param {*} modelType:模型类型
 * --------------------------------------------------------------------------------------------
 */
removeModel(modelType) {
    let viewer = getViewer();
    let model = viewer.scene.primitives._primitives.filter(t => {
        return t && t.type === modelType;
    });
    if (model && model.length) {
        model.forEach(item => {
            viewer.scene.primitives.remove(item);
        })
    }
}

控制gltf部分模型显隐

/**
 * @param {*} 
 * modelType:模型类型
 * data: {
            names: ['name1'],
            show: false
          }
 */
controlGltfModelShow(modelType, data) {
    let viewer = getViewer();
    let model = viewer.scene.primitives._primitives.filter(t => {
        return t && t.type === modelType;
    });
    if (model && model.length) {
        model.forEach(item => {
            item._nodeCommands.forEach(c => {
                if (!data.show) {
                	//c.command.owner.node.name: 子模型名称
                    c.show = !(data.names.includes(c.command.owner.node.name));
                } else {
                    c.show = true
                }
            })
        })
    }
}

控制gltf模型样式

/**
 * @param {*} 
 * modelType:模型类型
 * data: {
 		show: true,
        ids: ['id1']
 }
 */
controlGltfModelStyle(modelType, data) {
    let viewer = getViewer();
    let model = viewer.scene.primitives._primitives.filter(t => {
        return t && t.type === modelType;
    });
    if (model && model.length) {
        let x = 1;
        let flog = true
        //动态更改样式
        viewer.scene.preUpdate.addEventListener(() => {
            model.forEach(item => {
            	//item.modelId: gitf模型自定义属性
                if (data.show && item.modelId && data.ids.includes(item.modelId)) {
                    //动态更改透明度
                    if (flog) {
                        x = x - 0.03;
                        if (x <= 0.2) {
                            flog = false;
                        }
                    } else {
                        x = x + 0.03;
                        if (x >= 0.8) {
                            flog = true;
                        }
                    }
                    item.color =  Cesium.Color.RED.withAlpha(x)
                } else {
                    item.color = Cesium.Color.fromCssColorString(`rgb(255, 225, 225)`).withAlpha(1)
                }
            })
        });
    }
}

控制3dTiles部分模型显隐

/**
 * @param {*} 
 * modelType:模型类型
 * data: {
            names: ['name1'],
            show: false
          }
 */
export function control3dTilesModelShow(modelType, data) {
    let viewer = getViewer();
    let model = viewer.scene.primitives._primitives.filter(t => {
        return t && t.type === modelType;
    });
    if (model && model.length) {
        model.forEach(item => {
            item.style = new Cesium.Cesium3DTileStyle({
                show: {
                    evaluate: (feature) => {
                        if (!data.show) {
							//feature.getProperty("name"): 子模型名称
                            return !(data.names.includes(feature.getProperty("name")))
                        } else {
                            return true
                        }
                    }
                }
            });
        })
    }
}

控制3dTiles部分模型样式

/**
 * @param {*} 
	 modelType:模型类型
	 data: {
	 		show: true,
	        names: ['name1']
	 }
 */
var defaultStyle = []; 
control3dTilesModelStyle(modelType, data) {
    let viewer = getViewer();
    let model = viewer.scene.primitives._primitives.filter(t => {
        return t && t.type === modelType;
    });
    if (model && model.length) {
        if (data.show) {
            defaultStyle = []
        }
        let x = 1;
        let flog = true
        //动态更改样式
        viewer.scene.preUpdate.addEventListener(() => {
            model.forEach(item => {
                if (data.show) {
                    //保存默认样式
                    defaultStyle.push({
                        url: item._url,
                        style: new Cesium.Cesium3DTileStyle()
                    })
                    //动态更改透明度,实现闪烁动画效果
                    if (flog) {
                            x = x - 0.03;
                            if (x <= 0.2) {
                                flog = false;
                            }
                        } else {
                            x = x + 0.03;
                            if (x >= 0.8) {
                                flog = true;
                            }
                        }
                        item.style = new Cesium.Cesium3DTileStyle({
                            color: {
                                evaluateColor: function (feature, result) {
                                	//feature.getProperty("name"): 子模型名称
                                    if (data.names.includes(feature.getProperty("name"))) {
                                        return Cesium.Color.RED.withAlpha(x)
                                    }
                                    return Cesium.Color.WHITE;
                                }
                            }
                        });
                } else {
                    let obj = defaultStyle.find(sty => sty.url === item._url)
                    if (obj) {
                        item.style = obj.style
                    }
                }
            })
        });
        //设置固定样式
        /*model.forEach(item => {
            if (data.show) {
                //保存默认样式
                defaultStyle.push({
                    url: item._url,
                    style: new Cesium.Cesium3DTileStyle()
                })
                item.style = new Cesium.Cesium3DTileStyle({
                        color: {
                            evaluateColor: function (feature, result) {
                            	//feature.getProperty("name"): 子模型名称
                                if (data.names.includes(feature.getProperty("name"))) {
                                    return Cesium.Color.RED.withAlpha(0.5)
                                }
                                return Cesium.Color.WHITE;
                            }
                            //根据高度设置颜色
                            /*conditions : [
	                            ['${Height} >= 80', 'color("purple", 0.5)'],
	                            ['${Height} >= 30', 'color("red")'],
	                            ['true', 'color("blue")']
	                        ]*/
                        }
                    });
            } else {
                let obj = defaultStyle.find(sty => sty.url === item._url)
                if (obj) {
                    item.style = obj.style
                }
            }
        })*/
        //获取子模型feature
		/*
		let curModels= viewer.scene.primitives._primitives.filter(t => {
	        return t && t.type === modelType;
	    });
		curModels.forEach(model => {
                        if (model.root && model.root.children && model.root.children.length) {
                            model.root.children.forEach(modelChild => {
                                if (modelChild.content && modelChild.content.featuresLength) {
                                    let featuresLength = modelChild.content.featuresLength;
                                    for (let i = 0; i < featuresLength; i++) {
                                        let feature = modelChild.content.getFeature(i);
                                        //feature.getProperty("name"): 子模型名称
                                        //修改模型颜色
                                        //feature.color = Cesium.Color.fromCssColorString("#faff12").withAlpha(0.8)
                                        //恢复模型颜色
                                        //feature.color = new Cesium.Color(1, 1, 1, 1);
                                    }
                                }
                            })
                        }
                    })*/
        
    }
}

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值