• Cesium


    Cesium

    Cesium API

    demo 仓库地址

    一、开始

    1.1 token

    注册一个 Cesium Ion ,在 Access Tokens 的右侧的 Token 处,复制到 js 文件中,赋值到 token,并设置:

    Cesium.Ion.defaultAccessToken = token;
    
    • 1
    1.2 创建 Cesium

    使用 Cesium.Viewer() 创建一个 Cesium ,第一个参数是创建的 Cesium 容器( DOM )的 id 名,不需要加 #,第二个参数是配置项,用参数配置。

    const viewer = new Cesium.Viewer('', {
        geocoder: false, // 是否创建右上角的查询按钮(右上第一个)
        homeButton: false, // 是否创建 home 按钮(右上第二个)
        sceneModePicker: false, // 是否创建右上角的切换地图的按钮(右上第三个)
        baseLayerPicker: false, // 是否创建右上角 BaseLayerPicker 小部件(右上第四个)
        navigationHelpButton: false, // 是否创建右上角的导航帮助按钮(右上第五个
        // vrButton: true, // 是否创建右下角的 VR 按钮,默认值为 true
        animation: false, // 是否创建左下角的动画小部件
        fullscreenButton: false, // 是否创建右下角全屏按钮
        timeline: false, // 是否创建最下方的时间线
        infoBox: false, // 点击实体是否展示详情
        selectionIndicator: false, // 点击实体是否显示选中样式
        // 左下方的 Cesium logo 使用 css 删除
        terrainProvider: Cesium.createWorldTerrain(), // 加载地球椭球体
    });
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    更多配置

    二、创建点、线、面实体

    2.1 entities.add()
    // 点实体
    viewer.entities.add({
        position: position, // 格式为世界坐标的点位置
    	point: {
            show: ture, // 点是否可见
            pixelSize: Number, // 点的大小
            color: color, // 点的颜色
            outlineClor: color, // 边框颜色
            outlineWidth: Number, // 轮廓宽度
        },
    });
    // 线实体
    viewer.entities.add({
        polyline: {
            show: Boolean, // 线是否可见
            positions: positions, // 格式为世界坐标的线位置数组
            width: Number, // 线的宽度
            material: color, // 线的颜色
            clampToGround: Boolean, // 线是否固定在地面
        },
    });
    // 面实体
    viewer.entities.add({
        polygon: {
            show: Boolean, // 面是否可见
            hierarchy: positions, // 格式为世界坐标的面位置数组
            height: Number, // 面相对于椭球表面的高度
            fill: Boolean, // 面是否有填充
            material: color, // 面的填充颜色
            outline: Boolean, // 面是否有边框
            outlinColor: color, // 边框的颜色
            outlineWidth: Number, // 边框的宽度,无论设置为多少宽度始终只会显示为 1
            perPositionHeight: Boolean, // 面是否使用每个位置的高度
        },
    });
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    2.2 Cesium.TypeGraphices()
    // 点实体
    viewer.entities.add({
        position: position, // 格式为世界坐标的点位置
        point: new Cesium.PointGraphics({
            show: Boolean, // 点是否可见
            pixelSize: Number, // 点的大小
            color: color, // 点的颜色
            outlineClor: color, // 边框宽度
            outlineWidth: Boolean, // 轮廓颜色
        });
    });
    // 线实体
    viewer.entities.add({
        golyline: new Cesium.PolylineGraphics({
            show: Boolean, // 线是否可见
            positions: positions, // 格式为 Cartesian3 的线位置数组
            width: Number, // 线的宽度
            material: color, // 线的颜色
            clampToGround: Boolean, // 线是否固定在地面
        });
    });
    // 面实体
    viewer.entities.add({
        golygon: new Cesium.PolygonGraphics({
            show: Boolean, // 面是否可见
            hierarchy: positions, // 格式为 Cartesian3 的面位置数组
            height: Number, // 面相对于椭球表面的高度
            fill: Boolean, // 面是否有填充
            material: color, // 面的填充颜色
            outline: Boolean, // 面是否有边框
            outlinColor: color, // 边框的颜色
            outlineWidth: Number, // 边框的宽度,无论设置为多少宽度始终只会显示为 1
            perPositionHeight: Boolean, // 面是否使用每个位置的高度
        });
    });
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35

    三、格式转换

    Cesium中的坐标相互转换

    3.1 格式类型

    平面坐标系( Cartesian2

    new Cesium.Cartesian2(x, y)
    
    • 1

    笛卡尔空间直角坐标系-世界坐标( Cartesian3

    new Cesium.Cartesian3(x, y, z);
    
    • 1

    弧度

    new Cesium.Cartographic(lng, lat, height);
    
    • 1

    经纬度

    (lng, lat)
    
    • 1
    3.2 坐标转化
    3.2.1 经纬度和世界坐标
    // 经纬度转为世界坐标
    Cesium.Cartesian3.fromDregrees(lng, lat, height);
    // 世界坐标转为经纬度
    const ellipsoid = viewer.scene.globe.ellipsoid;
    const cartiesian3 = new Cesium.Cartesian3(x, y, z);
    const cartographic = ellipsoid.cartesianToCartographic(cartesian3);
    const lng = Cesium.Math.toDegrees(cartographic.longitude);
    const lat = Cesium.Math.toDegrees(cartographic.latitude);
    const height = cartographic.height;
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    封装为方法

    // 世界坐标转为经纬度
    // 参数可以是一个世界坐标,也可以是一组世界坐标数组
    function toLatAndLng(position) {
        if (Array.isArray(position)) {
            return position.map(item => toLatAndLng(item));
        } else {
            const cartographic = ellipsoid.cartesianToCartographic(position);
            const lng = Cesium.Math.toDegrees(cartographic.longitude);
            const lat = Cesium.Math.toDegrees(cartographic.latitude);
            const height = cartographic.height;
            return [lng, lat, height];
        }
    };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    3.2.2 平面坐标和世界坐标
    // 屏幕坐标转为世界坐标
    const pick1 = new Cesium.Cartesian2(0, 0);
    const cartesian = viewer.scene.globe.pick(viewer.camera.getPickRay(pick1), viewer.scene);
    // 世界坐标转为屏幕坐标
    Cesium.SceneTransforms.wgs84ToWindowCoordinates(scene, Cartesian3)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    3.2.3 弧度和经纬度
    // 弧度转为经纬度
    Cesium.Math.toRadians(degrees);
    // 经纬度转为弧度
    Cesium.Math.toDregees(radians);
    
    • 1
    • 2
    • 3
    • 4
    3.3 其他格式转化
    // 返回指定经度和纬度的二维区域
    new Cesium.Rectangle.fromDegrees(
    	Number, // 最西的经度
    	Number, // 最南端的纬度
    	Number, // 最东的经度
    	Number // 最北端的纬度
    );
    // 返回颜色
    Cesium.Color.fromCssColorString(
    	color // css 的颜色样式
    ).withAlpha(
    	Number // 颜色的透明度,0 - 1
    );
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    封装为方法

    // 跳转的到一个区域,且最后得到的图形是整个范围的 1/3
    function flyToRectangle(position, time) {
        const WE = position.east - position.west;
        const NS = position.north - position.south;
        viewer.camera.flyTo({
            destination: Cesium.Rectangle.fromDegrees(
            	position.west - WE,
             	position.south - NS,
            	position.east + WE,
                position.north + NS
            ),
            duration: time || 0.8,
        });
    };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    3.4 地球二三维切换
    // 切换为三维
    viewer.scene.morphTo3D({
        duration: Number // 切换花费的时间
    });
    // 切换为二维
    viewer.scene.morphTo2D({
        duration: Number // 切换花费的时间
    });
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    四、镜头跳转

    4.1 flyTo()
    // 跳转设置点或区域
    viewer.camera.flyTo({
        // destination: position, 跳转到某一点时,格式为 Cartesian3 的位置
        destination: Rectangle, // 跳转到某一区域
        duration: Number, // 镜头飞行时长
    });
    // 跳转某一实体
    viewer.flyTo(
        target, // 实体
        {
            duration: Number, // 镜头飞行时长
            maximumHeight: Number, // 镜头飞行的最大高度
            offset: new Cesium.HeadingPitchRangce(
                Number, // 航向角,格式为弧度
                Number, // 俯仰角,格式为弧度
                Number, // 据中心的距离
            ),
        },
    );
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    4.2 zoomTo()
    // 跳转某一实体,且可以设置航向角,俯仰角和据中心距离
    viewer.zommTo(
    	target, // 实体
        new Cesium.HeadingPitchRange(
            Number, // 航向角,格式为弧度
            Number, // 俯仰角,格式为弧度
            Number, // 据中心的距离
        ),
    );
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    五、导入数据源

    5.1 GeoJsonDataSource
    // 导入格式为 GeoJSON 或 TopoJSON 的实体
    viewer.dataSources.add(Cesium.GeoJsonDataSource.load(data, { // data 为需要加载的数据
        markerSize: Number, // 为每个点创建的地图图钉的默认大小
        stroke: Color, // 折线和多边形轮廓的默认颜色
        strokeWidth: Number, // 折线和多边形轮廓的默认宽度
        fill: Color, // 多边形内部的默认颜色
        clampToGround: Boolean, // 是否固定在地面
    })).then(dataSourcre => {
        console.log(dataSourcre);
    });
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    4.2 KmlDataSource
    // 导入格式为 KML 的实体
    viewer.dataSources.add(data, { // data 为需要加载的数据
        camera: camera, // 用于viewRefreshModes并将摄像机属性发送到网络链接的摄像机
        canvas: canvas, // 用于将查看器属性发送到网络链接的画布
        clampToGround: Boolean, // 是否固定在地面
    }).then(dataSource => {
        console.log(dataSource);
    });
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    六、事件

    事件解析

    6.1 事件类型

    鼠标左键

    事件类型含义
    LEFT_CLICK单击
    LEFT_DOUBLE_CLICK双击
    LEFT_DOWN左键按下
    LEFT_UP左键弹起

    鼠标中键

    事件类型含义
    MIDDLE_CLICK点击
    MIDDLE_DOWN中键按下
    MIDDLE_UP中键弹起

    鼠标右键

    事件类型含义
    RIGHT_CLICK点击
    RIGHT_DOWN右键按下
    RIGHT_UP右键弹起

    其他鼠标事件

    事件类型含义
    MOUSE_MOVE鼠标移动事件
    WHEEL鼠标滚轮事件
    6.2 Cesium.ScreenSpaceEventHandler()

    使用 Cesium.ScreenSpaceEventHandler() 获取需要注册点击事件的 Cesium

    const handler = new Cesium.ScreenSpaceEventHandler(viewer);
    
    • 1
    6.3 Cesium.ScreenSpaceEventType()

    使用 Cesium.ScreenSpaceEventType() 获取触发事件的条件,例如获取点击左键

    const LEFT_CLICK = Cesium.ScreenSpaceEventType(LEFT_CLICK);
    
    • 1
    6.4 handler.setInputAction()

    使用 handler.setInputAction() 监听触发的事件,第一个参数是触发事件调用的方法函数,第二个参数是触发事件的类型

    handler.setInputAction(event => {
        console.log(event);
    }, LEFT_CLICK);
    
    • 1
    • 2
    • 3

    event 中的位置格式是平面坐标

    6.4 viewer.scene.dirllPick()
    // 返回包含点的所有实体集合,是一个数组
    viewer.scene.dirllPick(
    	position, // 平面坐标
     	Number // 收集到指定个数的实体就停止获取,可选
    );
    
    • 1
    • 2
    • 3
    • 4
    • 5

    配合点击事件

    const handler = new Cesium.ScreenSpaceEventHandler(viewer.canvas);
    handler.setInputAction(event => {
        const entities = viewer.scene.dirllPick(event.position);
        console.log(entities);
    }, Cesium.ScreenSpaceEventType.LEFT_CLICK);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    6.5 viewer.selectedEntityChanged.addEventListener
    // 点击左键时,若点击的实体产生变化才会调用
    viewer.selectedEntityChanged.addEventListener(entity => {
        console.log(entity);
    })
    
    • 1
    • 2
    • 3
    • 4

    七、动态绘制点、线、面

    7.1 动态绘制点

    在鼠标移动事件中,第一次触发移动事件时,就创建一个点实体,以后触发移动事件时就先删除上一次触发移动事件创建的实体,再创建一个新的实体。

    7.2 动态绘制线

    动态绘制线与动态绘制点相似,但是,在绘制过程中, polyline 中的 positions 属性值需要使用 Cesium.CallbackProperty() 方法来获取。

    viewer.entities.add({
        polyline: {
            positions: new Cesium.CallbackProperty(function() {
                return positions;
            }, false),
            material: Color,
            width: Number,
        }
    });
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    7.3 动态绘制面

    动态绘制面 demo

    动态绘制面与动态绘制线相似,但是,在 polygon 中的 hierarchy 属性值除需要使用 Cesium.CallbackProperty() 方法来获取外,还需要使用 Cesium.PolygonHierarchy() 返回。

    viewer.entities.add({
        polygon: {
            hierarchy: new Cesium.CallbackProoerty(function() {
                return new Cesium.PolyHierarchy(positions);
            }, false),
            material: Color,
        }
    });
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    八、加载地图(高德)

    8.1 引入地图资源

    使用方法 Cesium.UrlTemplateImageryProvider() 引入地图资源

    // Cesium 加载高德矢量地图
    var layer = new Cesium.UrlTemplateImageryProvider({
        url: "http://webrd02.is.autonavi.com/appmaptile?lang=zh_cn&size=1&scale=1&style=8&x={x}&y={y}&z={z}",
        minimumLevel: 4,
        maximumLevel: 18
    });
    // Cesium 加载高德影像
    var imgLayer = new Cesium.UrlTemplateImageryProvider({
        url: "https://webst02.is.autonavi.com/appmaptile?style=6&x={x}&y={y}&z={z}",
        minimumLevel: 3,
        maximumLevel: 18
    });
    // Cesium 加载注记要素
    var annLayer = new Cesium.UrlTemplateImageryProvider({
        url: "http://webst02.is.autonavi.com/appmaptile?x={x}&y={y}&z={z}&lang=zh_cn&size=1&scale=1&style=8",
        minimumLevel: 3,
        maximumLevel: 18
    });
    
    // Cesium 加载天地图
    var dmap = new Cesium.UrlTemplateImageryProvider({
        url: "https://map.geoq.cn/ArcGIS/rest/services/ChinaOnlineStreetPurplishBlue/MapServer/tile/{z}/{y}/{x}",
        minimumLevel: 4,
        maximumLevel: 18 
    });
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    8.2 加载地图资源
    viewer.imageryLayers.addImageryProvider();
    
    • 1
    8.3 地图搜索

    高德地图 API

    九、计算长度、面积

    @turf/turf

    使用插件 turfCDN 引入

    <script src="https://cdn.jsdelivr.net/npm/@turf/turf@5/turf.min.js">script>
    
    • 1

    import 引入

    import turf as * from "@turf/turf";
    
    • 1
    9.1 根据长度计算长度
    // positions 需要计算线状实体的位置信息,是一个数组,每个元素是经纬度
    const polyline = turf.lineString(positions);
    const length = turf.length(polyline);
    
    • 1
    • 2
    • 3
    9.2 根据点经纬度计算面积
    // hierarchy 需要计算面状实体的位置信息,是一个数组,每个元素是经纬度,且第一个元素与最后一个元素要相同
    const polygon = turf.polygon([hirerachy]);
    const area = turf.area(polygon);
    
    • 1
    • 2
    • 3

    十、其他

    // 开启抗锯齿
    viewer.scene.postProcessStages.fxaa.enabled = true;
    // 取消默认的左键双击事件
    viewer.cesiumWidget.screenSpaceEventHandler.removeInputAction(Cesium.ScreenSpaceEventType.LEFT_DOUBLE_CLICK);
    
    • 1
    • 2
    • 3
    • 4
  • 相关阅读:
    [C4(NEim)2][Br]2双子型离子液体1,4-双(1-氰乙基咪唑諭基)丁烷二溴盐
    Rust编程中的线程间通信
    安卓程序执行入口
    几何等变图神经网络综述
    tcpdump抓包与iptables过滤的关系
    【阅读笔记】《深度学习》第三章:概率与信息论
    从头训练一个神经网络!教它学会莫奈风格作画!⛵
    二叉树入门算法题详解
    1.什么是闭包
    分类算法——ROC曲线与AUC指标(九)
  • 原文地址:https://blog.csdn.net/m0_49788155/article/details/126966718