项目中cesium使用方法

2023-12-29 09:29:50

cesium方法整理

一、安装依赖

// 安装cesium
npm install cesium --save
// 安装turf工具
npm install @truf/turf --save
// 安装cesium vite插件
npm install vite-plugin-cesim --save

二、项目中引用

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({}))

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

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

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

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

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())

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())

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))

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

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

let entity = viewer.entities.getById(id)

8.弧度角度转换

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

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

// 将经纬度转成笛卡尔坐标
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() )

// 获取实体具体数据
let data = entity.properties.data.getValue()

11.地图模式改变

// 切换到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(对象) )

Cesium.defined(对象)

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

// 移除所有图层
viewer.imageryLayers.removeAll()
// 添加底图
viewer.imageryLayers.addImageryProvider(electronic)

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

/**
 * @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.视图放大

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

16.视图缩小

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

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

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

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

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

19.添加线

/**
 * @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 ) )

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

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

/**
* 计算一个点是否在多边形里
* @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.经纬度转屏幕坐标

/**
 * 经纬度转屏幕坐标
 * @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
}

文章来源:https://blog.csdn.net/weixin_46054156/article/details/135282446
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。