整合营销服务商

电脑端+手机端+微信端=数据同步管理

免费咨询热线:

Cesium 的各种定位方法汇总-未完待续

Cesium 的各种定位方法汇总-未完待续
/*
 * @Author: 苹果园dog
 * @Date: 2020-10-31 21:50:33
 * @LastEditTime: 2020-11-05 23:06:14
 * @LastEditors: Please set LastEditors
 * @Description: Cesium 的各种定位方法汇总,只列出项目中经常使用的,如果不够灵活,可直接调用Cesium官方API,也很方便。
 * Cesium的定位从效果上包含两种:直接定位、飞行定位。在方法封装上,本狗姑且将直接定位分类为zoomTo系列,飞行定位分类flyTo。
 * 定位的对象上包括:坐标点、矩形范围、entities、3dtiles、gltf、kml、geojson、影像、地形、geometry 
 * Cesium的定位主要是使用Camera对象和Viewer对象,Viewer的定位zoomTo,flyTo等方法是较高级别的函数,可以定位到Entity、3dtiles、DataSource等添加到三维球上显示的实体,
 * Viewer的定位方法内部都是调用Camera的相关定位方法,针对不同的定位对象,通过一些列计算得出传入实体的合适定位范围和摄像机视角,然后定位,使用起来很方便。
 * Camera的flyTo、flyToBoundingSphere、lookat、setView等方法是较低级别函数,通过定位坐标和角度参数的传入,精细化控制定位视角,灵活。
 * @FilePath: \web\cesiumS\cesium\cesium\mytest\朝花夕拾\定位\cesiumLocateUtil.js
 */
var cesiumLocateUtil={
    zoomTo: {

    },
    flyTo: {
        /**
         * @description: 飞行定位到一个笛卡尔空间直角坐标点位置
         * @param {Cartesian3} destination 目标点 Cartesian3
         * @param {Number} heading  默认=0.0   偏航角 正北,由正北向东偏向为正
         * @param {*} pitch=-90     俯仰角 垂直向下, ENU局部坐标系中XY平面的旋转角度,平面下为负,上为正,
         * @param {*} range=0.0   距目标点距离
         * @param {*} duration=3   持续时间
         * @param {*} callBack=null   回调函数,定位完成后执行
         */
        flyToPoint: function (destination, heading=0.0, pitch=-90, range=0.0, duration=3, callBack=null) {
            if (!viewer) {
                console.log('三维球未初始化!');
                return;
            }
            if (!destination) {
                console.log('定位目标点不对!');
                return;
            }
            var boundingSphere=new Cesium.BoundingSphere(destination, 0.0);
            viewer.camera.flyToBoundingSphere(boundingSphere, {
                duration: duration,
                maximumHeight: undefined,
                complete: function () {
                    if (callBack) {
                        callBack();
                    }else{
                        console.log('定位失败!');
                    }
                },
                cancel: function () {
                    console.log('定位取消!');
                },
                offset: {
                    heading: Cesium.Math.toRadians(heading),
                    pitch: Cesium.Math.toRadians(pitch),
                    range: range
                },
            });

        },

        /**
         * @description: 飞行定位到一个矩形
         * @param {Array.<Cartesian3>} cartesians 笛卡尔坐标数组 Array.<Cartesian3>
         * @param {Number} heading=0.0   偏航角 正北,由正北向东偏向为正
         * @param {*} pitch=-90     俯仰角=-90 ENU局部坐标系,XY平面的旋转角度,平面下为负,上为正,
         * @param {*} scale=1.0   范围缩放倍率
         * @param {*} duration=3   持续时间
         * @param {*} callBack=null   回调函数,定位完成后执行
         * @return {*}
         */
        flyToRectangle: function (cartesians, heading=0.0, pitch=-90, scale=1.0, duration=3, callBack=null) { 
            if (!viewer) {
                console.log('三维球未初始化!');
                return;
            }
            if (!Array.isArray(cartesians)) {
                console.log('定位范围不对!');
                return;
            }         
            if(scale<0.1){
                scale=1.0;
            }  
            var rec=Cesium.Rectangle.fromCartesianArray(cartesians);
            var boundingSphere=Cesium.BoundingSphere.fromRectangle3D(rec);
            boundingSphere.radius=boundingSphere.radius*scale;
            viewer.camera.flyToBoundingSphere(boundingSphere, {
                duration: duration,
                maximumHeight: undefined,
                complete: function () {
                    if (callBack) {
                        callBack();
                    }else{
                        console.log('定位失败!');
                    }
                },
                cancel: function () {
                    console.log('定位取消!');
                },
                offset: {
                    heading: Cesium.Math.toRadians(heading),
                    pitch: Cesium.Math.toRadians(pitch),
                    range: 0.0
                }
            });
        },

        flyToEntity(entity,){

        }
    }

}


ite+Vue3+Cesium项目模版

Cesium是AGI公司计算机图形开发小组与2011年研发的三维地球和地图可视化开源JavaScript库,Cesium一词来源于化学元素铯,铯是制造原子钟的关键元素,研发小组通过命名强调Cesium产品精益求精,专注时间数据可视化。Cesium为三维GIS提供了一个高效的数据可视化平台

使用viet创建vue3项目

创建vue3项目 这里使用的是vue的模版。如果选择其他框架,则不用加--template vue
pnpm create vite vite+vue3+cesium --template vue

进入项目 cd vite-app

安装依赖 pnpm install

运行项目 pnpm run dev


看到这个页面就说明vite+vue3的项目初始化成功了,下面就是安装和初始化cesium框架和cesium的vite插件了 在vite项目中要正常使用cesium我目前知道的有两种方法。

下面先讲第一种,也就是使用vite-plugin-cesium这个插件 首先找到这个插件的git仓库 https://github.com/nshen/vite-plugin-cesium

第一种方法

install

npm i cesium vite-plugin-cesium vite -D

yarn add cesium vite-plugin-cesium vite -D

Usage

在vite.config.js文件中添加cesium的插件

import { defineConfig } from 'vite';
import cesium from 'vite-plugin-cesium';
export default defineConfig({
  plugins: [cesium()]
});

下面去页面中初始化cesium

<script setup>
import {onMounted, ref} from 'vue'
import * as Cesium from 'cesium'

//cesium初始化必须写在mounted生命周期里面,否则会报错"Element with id "cesiumContainer" does not exist in the document."
onMounted(()=> {
  const viewer=new Cesium.Viewer('cesiumContainer', {
    //这里是配置项
  })
})
</script>

<template>
  <div id="cesiumContainer"></div>
</template>


<style scoped>
#cesiumContainer {
  width: 100vw;
  height: 100vh;
}
</style>


发现样式有些问题。我一看,哦,原来是style.css中有模版的默认样式的影响。 把style.css中的默认样式删除就好了


这才是正确的姿势嘛!

第2种方法

第二种方法就是本地引入,把下载好的cesium依赖包(node_modules里面)复制放到public里面, 然后在index.html里面引入cesium和css文件

<script type="text/javascript" src="./public/Cesium/Cesium.js"></script>

<link rel="stylesheet" href="./public/Cesium/Widgets/widgets.css">

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <link rel="icon" type="image/svg+xml" href="/vite.svg" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Vue+Cesium</title>
      <link rel="stylesheet" href="./public/Cesium/Widgets/widgets.css">

![img_3.png](https://p6-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/06e65d12be0540ddb17c9a7b2476a7e2~tplv-k3u1fbpfcp-watermark.image?)
  </head>
  <body>
    <div id="app"></div>
    <script type="module" src="/src/main.js"></script>
    <script type="text/javascript" src="./public/Cesium/Cesium.js"></script>

![img_1.png](https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/cd519580e2904edbb34dc4d0dba5a00b~tplv-k3u1fbpfcp-watermark.image?)
  </body>
</html>


然后同样的去页面种初始化cesium就可以了。

不过还有一个小问题,在控制台中我发现有个报错:

VM19:1 Blocked script execution in 'about:blank' because the document's frame is sandboxed and the 'allow-scripts' permission is not set.

目前还没找到解决的办法

下篇文章将介绍vite+react+cesium应该如何搭建react项目框架,以及cesium的一些概念和基本知识。

们知道有一种快速建模的方式叫倾斜摄影,适用大场景的建模,快速逼真高效,本文分享倾斜摄影如何与cesium结合的话题,那么什么是倾斜摄影呢?倾斜摄影适用什么场景的建模?倾斜摄影相对于纯手工建模方式有什么优劣势?倾斜摄影数据如何导入到cesium中,代码示例是什么?希望本文能够让大家对二者有个大体认识。

倾斜摄影概述

倾斜摄影(Oblique Photography)是一种航空摄影技术,它使用多个相机从不同的角度同时拍摄地面,从而获取建筑物和其他地物的立体信息。这些图像可以用来生成高精度的三维模型,包括地形模型、纹理网格和三维建筑模型。这种方法特别适合于城市环境和大范围区域的快速三维重建。

适用场景

倾斜摄影适用于:

  • 城市三维建模
  • 地形和地貌的三维重建
  • 道路、桥梁等基础设施建模
  • 自然灾害评估和应急响应
  • 历史遗迹和考古遗址的记录
  • 规划和设计项目

相对于纯手工建模的优势和劣势

优势:

  • 快速建模:倾斜摄影可以迅速覆盖大面积区域,而手工建模则耗时且成本高。
  • 高精度和细节:自动化的数据处理可以达到高精度,且能够捕捉到建筑物和地形的细节。
  • 真实感:由真实照片生成的纹理,使得模型具有更高的真实感。
  • 自动化:大部分过程可以自动化,减少了人工干预的需求。

劣势:

  • 数据处理需求:需要专业的软件和计算资源来处理和分析大量图像数据。
  • 光照和阴影问题:不同光照条件下的图像可能影响模型质量。
  • 隐私和安全问题:可能涉及个人隐私和敏感地点的安全问题。



导入倾斜摄影数据到Cesium中

Cesium支持加载3D Tiles格式的数据,这意味着你需要将倾斜摄影产生的OSGB或其他格式的数据转换成3D Tiles格式。这个转换过程通常通过专门的工具完成,例如:

  • Cesium ion
  • 3D Tiles Converter (cesium.com/downloads/)
  • 其他第三方工具

一旦转换完成,你就可以使用Cesium JavaScript API来加载数据。下面是一个简单的代码示例:

Javascript
1// 创建Cesium Viewer实例
2var viewer=new Cesium.Viewer('cesiumContainer');
3
4// 定义3D Tiles数据集
5var tileset=new Cesium.Cesium3DTileset({
6    url : 'path/to/your/tileset.json'
7});
8
9// 将数据集添加到Viewer中
10viewer.scene.primitives.add(tileset);
11
12// 调整视图以聚焦数据集
13viewer.zoomTo(tileset);

在这个例子中,tileset.json是3D Tiles数据集的根文件,它包含了加载和渲染所有3D Tiles所需的信息。

倾斜摄影结合Cesium为快速构建大场景的三维模型提供了强大工具。通过使用现代的WebGIS技术,如Cesium,可以轻松地将这些模型集成到交互式的地理空间应用中,为用户提供沉浸式体验。



大象数据工场→10年经验的可视化/数字孪生领域的老司机,专注大数据设计和前端交互部分。关注我,带您了解最新的观点、技术、干货,如有需求可私信。