项目中cesium使用方法

cesium方法整理

一、安装依赖

javascript 复制代码
// 安装cesium
npm install cesium --save
// 安装turf工具
npm install @truf/turf --save
// 安装cesium vite插件
npm install vite-plugin-cesim --save

二、项目中引用

javascript 复制代码
import * as Cesium from 'cesium'
import 'cesium/Build/Cesium/Widgets/widgets.css'
import * as turf from '@turf/turf'

// 配置地图根目录
window.CESIUM_BASE_URL = '../Cesium'

三、具体方法介绍总结

1,生成地图电子底图(new Cesium.UrlTemplateImageryProvider({}))

javascript 复制代码
let electronic = new Cesium.UrlTemplateImageryProvider({
    url: 'url',  // url 地址
    fileExtension: "jpg" // 类型
})

2,生成地图卫星底图( new Cesium.ArcGisMapServerImageryProvider({}) )

javascript 复制代码
let satellite = new Cesium.ArcGisMapServerImageryProvider({
    url: 'https://services.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer'
})

3,初始实例化及相关配置( new Cesium.Viewer(id, {}) )

javascript 复制代码
let viewer = new Cesium.Viewer(id, {
    //需要进行可视化的数据源的集合
    animation: false, //是否显示动画控件
    selectionIndicator: false,
    shouldAnimate: true, // 是否使用动画
    homeButton: false, //是否显示Home按钮
    fullscreenButton: false, //是否显示全屏按钮
    baseLayerPicker: false, //是否显示图层选择控件
    geocoder: false, //是否显示地名查找控件
    timeline: false, //是否显示时间线控件
    sceneModePicker: false, //是否显示投影方式控件
    navigationHelpButton: false, //是否显示帮助信息控件
    infoBox: false, //是否显示点击要素之后显示的信息
    requestRenderMode: true, //启用请求渲染模式
    scene3DOnly: false, //每个几何实例将只能以3D渲染以节省GPU内存
    sceneMode: (config.mode == 'earth' && Cesium.SceneMode.SCENE3D) || (config.mode == '3D' && Cesium.SceneMode.COLUMBUS_VIEW) || Cesium.SceneMode.SCENE2D, //初始场景模式 1 2D模式 2 2D循环模式 3 3D模式  Cesium.SceneMode
    fullscreenElement: document.body, //全屏时渲染的HTML元素 暂时没发现用处
    imageryProvider: (config.baseLayer == 'satellite' && config.satellite) || config.electronic
});

//隐藏cesium左下角logo
viewer._cesiumWidget._creditContainer.style.display = 'none';
// 开启抗锯齿
viewer.scene.postProcessStages.fxaa.enabled = true
// 相机高度最大值,限制缩小级别
let cameraHeight = 1.1e7
viewer.scene.screenSpaceCameraController.maximumZoomDistance = cameraHeight * 3;

// 深度开启或关闭
viewer.scene.globe.depthTestAgainstTerrain = false;

// 取消默认的双击放大时间
viewer.cesiumWidget.screenSpaceEventHandler.removeInputAction(Cesium.ScreenSpaceEventType.LEFT_DOUBLE_CLICK);

// 引起事件监听的相机变化幅度
viewer.camera.percentageChanged = 0.02;

4, 注册地图事件(new Cesium.ScreenSpaceEventHandler())

javascript 复制代码
var handler = new Cesium.ScreenSpaceEventHandler(viewer.scene.canvas);
// 监听地图鼠标左击
handler.setInputAction((click) => leftClickEvent(click), Cesium.ScreenSpaceEventType.LEFT_DOWN)
function leftClickEvent(click) {
    // 鼠标左击回调函数
}
// 监听地图鼠标右击
handler.setInputAction((click) => rightClickEvent(click), Cesium.ScreenSpaceEventType.RIGHT_CLICK)
function rightClickEvent(click) {
    // 鼠标右击回调函数
}

// 销毁句柄
handler.destroy()

5,获取鼠标点击位置(世界坐标系) (viewer.camera.getPickRay())

javascript 复制代码
1、获取椭球上的点的经纬度(椭球上的点)
let handler = new Cesium.ScreenSpaceEventHandler(viewer.scene.canvas);
handler.setInputAction(function(event) {
    // 世界坐标、笛卡尔坐标
    // enent.position 为屏幕坐标
    let cartesian = viewer.camera.pickEllipsoid(event.position);
    // 地理坐标 弧度
    let cartographic = Cesium.Cartographic.fromCartesian(cartesian);
    // 地理坐标 经纬度
    let lng = Cesium.Math.toDegrees(cartographic.longitude); // 经度
    let lat = Cesium.Math.toDegrees(cartographic.latitude); // 纬度
    let alt = cartographic.height; // 高度,椭球面height永远等于0
    let coordinate = {
        longitude: Number(lng.toFixed(6)),
        latitude: Number(lat.toFixed(6)),
        altitude: Number(alt.toFixed(2))
    };
    console.log(coordinate);
}, Cesium.ScreenSpaceEventType.LEFT_CLICK);

2、获取地表面的点的经纬度(地形上的点)
let handler = new Cesium.ScreenSpaceEventHandler(viewer.scene.canvas);
handler.setInputAction(function(event){
    // 笛卡尔3 射线的位置和方向  
    // event.position 屏幕坐标
    let ray = viewer.camera.getPickRay(event.position);
    // 射线与渲染的地球表面之间的交点  世界坐标、笛卡尔坐标
    let cartesian = viewer.scene.globe.pick(ray, viewer.scene);
    // 地理坐标 弧度
    let cartographic = Cesium.Cartographic.fromCartesian(cartesian);
    // 地理坐标 经纬度
    let lng = Cesium.Math.toDegrees(cartographic.longitude); // 经度
    let lat = Cesium.Math.toDegrees(cartographic.latitude); // 纬度
    let alt = cartographic.height; // 高度
    let coordinate = {
        longitude: Number(lng.toFixed(6)),
        latitude: Number(lat.toFixed(6)),
        altitude: Number(alt.toFixed(2))
    };

}, Cesium.ScreenSpaceEventType.LEFT_CLICK);

3、获取场景里的点的经纬度(模型上的点)

let handler = new Cesium.ScreenSpaceEventHandler(viewer.scene.canvas);
handler.setInputAction(function (event) {
    let cartesian = viewer.scene.pickPosition(event.position);
    let cartographic = Cesium.Cartographic.fromCartesian(cartesian);
    let lng = Cesium.Math.toDegrees(cartographic.longitude); // 经度
    let lat = Cesium.Math.toDegrees(cartographic.latitude); // 纬度
    let alt = cartographic.height; // 高度
    let coordinate = {
        longitude: Number(lng.toFixed(6)),
        latitude: Number(lat.toFixed(6)),
        altitude: Number(alt.toFixed(2))
    };
    console.log(coordinate);
}, Cesium.ScreenSpaceEventType.LEFT_CLICK);

6,点击获取实体对象(viewer.scene.pick(position))

javascript 复制代码
// 点击获取实体对象
// e.position 屏幕坐标
let pickedObject = viewer.scene.pick(e.position)

7,点击获取entity实体( viewer.entities.getById() )

javascript 复制代码
let entity = viewer.entities.getById(id)

8.弧度角度转换

javascript 复制代码
// 将角度转成弧度
Cesium.Math.toRadians(degrees)
// 将弧度转成角度 
Cesium.Math.toDegrees(radians)
// 将笛卡尔坐标系中的点转换为地理坐标系中的点。
Cesium.Ellipsoid.cartesianToCartographic(cartesian)
// 将地理坐标系中的点转换为笛卡尔坐标系中的点。
Cesium.Ellipsoid.cartographicToCartesian(cartographic)

9.移动视图,设置相机飞行( viewer.camera.flyTo({}) )

javascript 复制代码
// 将经纬度转成笛卡尔坐标
Cesium.Cartesian3.fromDegrees()
// 将经纬度坐标数组转成笛卡尔坐标数组
Cesium.Cartesian3.fromDegreesArray(degreesArray)

viewer.camera.flyTo({
    destination: Cesium.Cartesian3.fromDegrees(119.36401386990066, 31.18535721814696, 120000),
    orientation: {
        heading: Cesium.Math.toRadians(345.0),
        pitch: Cesium.Math.toRadians(-60.0),
        roll: Cesium.Math.toRadians(0.0)
    }
})

10. 获取实体 具体 数据( entity.properties.data.getValue() )

javascript 复制代码
// 获取实体具体数据
let data = entity.properties.data.getValue()

11.地图模式改变

javascript 复制代码
// 切换到2D模式
viewer.scene.morphTo2D(1)
// 切换到3D模式
viewer.scene.morphTo3D()
// 切换到哥伦布模式
viewer.scene.morphToColumbusView()


// 获取中心视图 2D 3D
let centerPosition = getCenterPosition(),
// 哥伦布模式 记录之前的变化矩阵和距离
let originalView = getViewTransform(viewer)

/**
 * @description: 获取变换矩阵和到中心点的距离
 * @param {*} viewObj 地图对象
 * @return {transform, distance} 变换矩阵,距离
 */
function getViewTransform(viewObj) {
    let position = getCenterPosition()
    if (!position) return
    // 中心点
    var centerPosition = Cesium.Cartesian3.fromDegrees(position.lon, position.lat, 0)
    // 相机点
    var endLat = Cesium.Math.toDegrees(viewObj.camera.positionCartographic.latitude)
    var endlng = Cesium.Math.toDegrees(viewObj.camera.positionCartographic.longitude)
    var height = viewObj.camera.positionCartographic.height;
    var endPosition = Cesium.Cartesian3.fromDegrees(endlng, endLat, height)
    // 距离
    var distance = Cesium.Cartesian3.distance(centerPosition, endPosition)
    // 矩阵
    var transform = Cesium.Transforms.eastNorthUpToFixedFrame(Cesium.Cartesian3.fromDegrees(position.lon, position.lat));
    return {
        transform: transform,
        distance: distance
    }
}

/**
 * @description:获取地图中心点
 * @return {lon, lat, height}  经度,纬度,高度
 */
function getCenterPosition() {
    let centerResult = viewer.camera.pickEllipsoid(
        new Cesium.Cartesian2(
            viewer.canvas.clientWidth / 2,
            viewer.canvas.clientHeight / 2,
        ),
    )
    let height = viewer.camera.positionCartographic.height || 10000;
    if (!Cesium.defined(centerResult)) return false
    let curPosition = Cesium.Ellipsoid.WGS84.cartesianToCartographic(centerResult);
    let curLongitude = (curPosition.longitude * 180) / Math.PI;
    let curLatitude = (curPosition.latitude * 180) / Math.PI;
    return {
        lon: curLongitude,
        lat: curLatitude,
        height: height
    }
}

// 监听场景转换完成事件
viewer.scene.morphComplete.addEventListener(() =>{
    // 延迟相机转场
    let timeout = setTimeout(() => {
        if (config.mode == '2D' || config.mode == 'earth') {
            if (!centerPosition) return
            let position = Cesium.Cartesian3.fromDegrees(centerPosition.lon, centerPosition.lat, centerPosition.height)
            viewer.camera.flyTo({
                   destination: position,
            });
         } else {
            if (!originalView) return
            var heading = viewer.camera.heading;
            var pitch = viewer.camera.pitch;
            viewer.camera.lookAtTransform(originalView.transform, new Cesium.HeadingPitchRange(heading, pitch, originalView.distance));
         }
         // 解除lookAtTransform的锁定
         viewer.camera.lookAtTransform(Cesium.Matrix4.IDENTITY)
         clearTimeout(timeout)
    }, 1000)
})

12.cesium 是否定义了对象( Cesium.defined(对象) )

javascript 复制代码
Cesium.defined(对象)

13.移除所有地图底图图层,添加地图底图( viewer.imageryLayers.removeAll(), viewer.imageryLayers.addImageryProvider() )

javascript 复制代码
// 移除所有图层
viewer.imageryLayers.removeAll()
// 添加底图
viewer.imageryLayers.addImageryProvider(electronic)

14.卷帘图,把视图分割成两部分,每部分加载不同的底图

javascript 复制代码
/**
 * @description: 卷帘图:把视图分割成两部分,每部分加载不同的底图
 */
function initJuanlian() {
    // 添加卷帘对比图
    let layers = viewer.imageryLayers;
    let leftMap = layers.addImageryProvider(config.electronic)
    let rightMap = layers.addImageryProvider(config.satellite);
    // 设置位置左右放置
    leftMap.splitDirection = Cesium.SplitDirection.LEFT;
    rightMap.splitDirection = Cesium.SplitDirection.RIGHT

    // 分割占比
    let slider = document.getElementById('juanlian');
    slider.style.display = 'block';
    viewer.scene.splitPosition = (slider.offsetLeft) / (slider.parentElement.offsetWidth);

    // 事件
    let handler = new Cesium.ScreenSpaceEventHandler(slider);
    let moveActive = false;

    handler.setInputAction(function () {
        moveActive = true;
    }, Cesium.ScreenSpaceEventType.LEFT_DOWN);
    handler.setInputAction(function () {
        moveActive = true;
    }, Cesium.ScreenSpaceEventType.PINCH_START);

    handler.setInputAction((e) => sliderMove(e, moveActive), Cesium.ScreenSpaceEventType.MOUSE_MOVE);
    handler.setInputAction((e) => sliderMove(e, moveActive), Cesium.ScreenSpaceEventType.PINCH_MOVE);

    handler.setInputAction(function () {
        moveActive = false;
    }, Cesium.ScreenSpaceEventType.LEFT_UP);
    handler.setInputAction(function () {
        moveActive = false;
    }, Cesium.ScreenSpaceEventType.PINCH_END);
}

/**
 * @description: 分割线移动
 * @param {*} movement 
 * @param {*} moveActive 
 */
function sliderMove(movement, moveActive) {
    if (!moveActive) {
        return;
    }
    let slider = document.getElementById('juanlian');
    let relativeOffset = movement.endPosition.x;
    let splitPosition = (slider.offsetLeft + relativeOffset) / slider.parentElement.offsetWidth;
    slider.style.left = 100.0 * splitPosition + '%';
    viewer.scene.splitPosition = splitPosition;
}

15.视图放大

javascript 复制代码
/**
 * @description: 视图放大
 */
function zoomInView() {
    var position = viewer.camera.positionCartographic;
    viewer.camera.moveForward(position.height * 0.5)
}

16.视图缩小

javascript 复制代码
/**
 * @description: 视图缩小
 */
function zoomOutView() {
    var position = viewer.camera.positionCartographic;
    viewer.camera.moveBackward(position.height * 0.5)
}

17.移除实体(viewer.entities.remove(entity))

javascript 复制代码
// 移除实体
viewer.entities.remove(entity)

18.创建CustomDataSource集合( new Cesium.CustomDataSource(name) )

javascript 复制代码
// 创建 CustomDataSource 集合
let drawCollection = new Cesium.CustomDataSource(name)
// viewer.dataSources添加集合
viewer.dataSources.add(drawCollection)

19.添加线

javascript 复制代码
/**
 * @description: 添加线
 * @param {*} positions 
 */
function addLine(positions) {
    let line = new Cesium.Entity({
        name: '直线',
        type: 'polyline',
        polyline: {
            positions: new Cesium.CallbackProperty(() => positions, false),
            width: 2,
            material: Cesium.Color.fromCssColorString("#1565c2").withAlpha(1),
            clampToGround: true,
            classificationType: Cesium.ClassificationType.BOTH
        },
    })
    // 添加到集合
    let _line = drawCollection.entities.add(line);
    return _line
}

20.两点之间的距离( Cesium.Cartesian3.distance( points, points ) )

javascript 复制代码
// 两点间的距离
// points 笛卡尔坐标 
// distance 单位为米
let distance = Cesium.Cartesian3.distance(points,points)

21.算法 计算一个点是否在多边形里

javascript 复制代码
/**
* 计算一个点是否在多边形里
* @param {Object} pt 标注点
* @param {Object} poly 多边形数组
*/
function isInsidePolygon(pt, poly) {
    for (var c = false, i = -1, l = poly.length, j = l - 1; ++i < l; j = i)
        ((poly[i].lat <= pt.lat && pt.lat < poly[j].lat) || (poly[j].lat <= pt.lat && pt.lat < poly[i].lat)) &&
            (pt.lng < (poly[j].lng - poly[i].lng) * (pt.lat - poly[i].lat) / (poly[j].lat - poly[i].lat) + poly[i].lng) &&
            (c = !c);
    return c;
}

22.经纬度转屏幕坐标

javascript 复制代码
/**
 * 经纬度转屏幕坐标
 * @param {*} latlng 经纬度
 * @return cartesian2-屏幕坐标
 */
function latlngToWindowCoordinates(latlng) {
    let cartesian3 = Cesium.Cartesian3.fromDegrees(latlng.lon, latlng.lat, 0)
    let cartesian2 = Cesium.SceneTransforms.wgs84ToWindowCoordinates(viewer.scene, cartesian3);
    return cartesian2
}
相关推荐
gis_rc3 天前
python下shp转3dtiles
python·3d·cesium·3dtiles·数字孪生模型
grasperp4 天前
3DTiles数据切片工具,支持LAS、OBJ、FBX 3DTiles怎么切片?3DTiles切片
cesium·3dtiles·三维gis·3dtiles切片·数据切片
duansamve6 天前
Cesium中实现在地图上移动/旋转点、线、面
cesium
冥界摄政王7 天前
CesiumJS学习第四章 替换指定3D建筑模型
3d·vue·html·webgl·js·cesium
冥界摄政王9 天前
Cesium学习第二章 camera 相机
node.js·html·vue3·js·cesium
冥界摄政王10 天前
Cesium学习第一章 安装下载 基于vue3引入Cesium项目开发
vue·vue3·html5·webgl·cesium
你们瞎搞11 天前
Cesium加载20GB航测影像.tif
前端·cesium·gdal·地图切片
闲云一鹤13 天前
Cesium 使用 Turf 实现坐标点移动(偏移)
前端·gis·cesium
二狗哈13 天前
Cesium快速入门34:3dTile高级样式设置
前端·javascript·算法·3d·webgl·cesium·地图可视化
二狗哈14 天前
Cesium快速入门33:tile3d设置样式
3d·状态模式·webgl·cesium·地图可视化