cesium学习笔记(问题记录)——(三)

一、根据点跟角度计算另一点坐标(三维球体)

export const getAnotherPoint = (lon: number, lat: number, angle: number, distance: number) => {
   
   
    // WGS84坐标系
    var a = 6378137;	// 赤道半径
    var b = 6356752.3142;	// 短半径
    var f = 1 / 298.257223563;	// 扁率

    var alpha1 = angle * (Math.PI / 180)
    var sinAlpha1 = Math.sin(alpha1);
    var cosAlpha1 = Math.cos(alpha1);
    var tanU1 = (1 - f) * Math.tan(lat * (Math.PI / 180));
    var cosU1 = 1 / Math.sqrt((1 + tanU1 * tanU1)), sinU1 = tanU1 * cosU1;
    var sigma1 = Math.atan2(tanU1, cosAlpha1);
    var sinAlpha = cosU1 * sinAlpha1;
    var cosSqAlpha = 1 - sinAlpha * sinAlpha;
    var uSq = cosSqAlpha * (a * a - b * b) / (b * b);
    var A = 1 + uSq / 16384 * (4096 + uSq * (-768 + uSq * (320 - 175 * uSq)));
    var B = uSq / 1024 * (256 + uSq * (-128 + uSq * (74 - 47 * uSq)));
    var sigma = distance / (b * A), sigmaP = 2 * Math.PI;
    let sinSigma = 0
    let cosSigma = 0
    let cos2SigmaM = 0
    while (Math.abs(sigma - sigmaP) > 1e-12) {
   
   
        cos2SigmaM = Math.cos(2 * sigma1 + sigma);
        sinSigma = Math.sin(sigma);
        cosSigma = Math.cos(sigma);
        var deltaSigma = B * sinSigma * (cos2SigmaM + B / 4 * (cosSigma * (-1 + 2 * cos2SigmaM * cos2SigmaM) -
            B / 6 * cos2SigmaM * (-3 + 4 * sinSigma * sinSigma) * (-3 + 4 * cos2SigmaM * cos2SigmaM)));
        sigmaP = sigma;
        sigma = distance / (b * A) + deltaSigma;
    }

    var tmp = sinU1 * sinSigma - cosU1 * cosSigma * cosAlpha1;
    var lat2 = Math.atan2(sinU1 * cosSigma + cosU1 * sinSigma * cosAlpha1,
        (1 - f) * Math.sqrt(sinAlpha * sinAlpha + tmp * tmp));
    var lambda = Math.atan2(sinSigma * sinAlpha1, cosU1 * cosSigma - sinU1 * sinSigma * cosAlpha1);
    var C = f / 16 * cosSqAlpha * (4 + f * (4 - 3 * cosSqAlpha));
    var L = lambda - (1 - C) * f * sinAlpha *
        (sigma + C * sinSigma * (cos2SigmaM + C * cosSigma * (-1 + 2 * cos2SigmaM * cos2SigmaM)));
    return {
   
    lon: Number(lon) + L * (180 / Math.PI), lat: lat2 * (180 / Math.PI) };
}

二、渐变材质

export const getMaterial = () => {
   
   
    let appearance = new Cesium.MaterialAppearance({
   
   
        vertexShaderSource: `
            attribute vec3 position3DHigh;  
            attribute vec3 position3DLow;
            attribute float batchId;
            varying vec4 v_positionEC;
            attribute vec4 color;
            varying vec4 v_color;
            void main(){
                v_color = color;
                vec4 p = czm_computePosition(); // 获取模型相对于视点位置
                vec4 eyePosition = czm_modelViewRelativeToEye * p; // 由模型坐标 得到视点坐标
                v_positionEC =  czm_inverseModelView * eyePosition;   // 视点在 模型坐标系中的位置
                gl_Position = czm_modelViewProjectionRelativeToEye * p;  // 视点坐标转为屏幕坐标
            }`,
        fragmentShaderSource: `      
            varying vec4 v_positionEC;
            varying vec3 v_normalEC;
            varying vec4 v_color;
            void main() {
                float l = sqrt(pow(v_positionEC.x,2.0) + pow(v_positionEC.y,2.0) + pow(v_positionEC.z,2.0)); // 距离模型坐标系原点的距离
                float cy3 = fract((abs(l-27.0))/40.0); 
                // 修改渐变方向 float cy3 = 1- fract((abs(l-27.0))/40.0); 
                gl_FragColor = vec4(v_color.rgb,cy3);
            }
            `,
    })
    return appearance
}

三、根据两点坐标获取偏航角和俯仰角

function getHeadingPitch(fromPosition, toPosition) {
   
   
    let finalPosition = new Cesium.Cartesian3();
    let matrix4 = Cesium.Transforms.eastNorthUpToFixedFrame(fromPosition);
    Cesium.Matrix4.inverse(matrix4, matrix4);
    Cesium.Matrix4.multiplyByPoint(matrix4, toPosition, finalPosition);
    Cesium.Cartesian3.normalize(finalPosition, finalPosition);
    const resultHead = Cesium.Math.toDegrees(Math.atan2(finalPosition.x, finalPosition.y))
    const resultPitch = Cesium.Math.toDegrees(Math.asin(finalPosition.z))
    return {
   
   resultHead ,resultPitch };
}

四、添加实体

(一)点

//entities.add(entity) 
viewer.entities.add({
   
   
  // fromDegrees(经度,纬度,高度,椭球,结果)从以度为单位的经度和纬度值返回Cartesian3位置
     position: Cesium.Cartesian3.fromDegrees(108, 34, 10),
     point: {
   
   
       // 点的大小(像素)
       pixelSize: 5,
       // 点位颜色,fromCssColorString 可以直接使用CSS颜色
       color: Cesium.Color.fromCssColorString('#ee0000'),
       // 边框颜色
       outlineColor: Cesium.Color.fromCssColorString('#fff'),
       // 边框宽度(像素)
       outlineWidth: 2,
       // 显示在距相机的距离处的属性,多少区间内是可以显示的
       distanceDisplayCondition: new Cesium.DistanceDisplayCondition(0, 1500),
       // 是否显示
       show: true
     }
   });

(二)线

viewer.entities.add({
   
   
     polyline: {
   
   
       // fromDegrees返回给定的经度和纬度值数组(以度为单位),该数组由Cartesian3位置组成。
       // Cesium.Cartesian3.fromDegreesArray([经度1, 纬度1, 经度2, 纬度2,])
       // Cesium.Cartesian3.fromDegreesArrayHeights([经度1, 纬度1, 高度1, 经度2, 纬度2, 高度2])
       positions: Cesium.Cartesian3.fromDegreesArray([
         120.9677706, 30.7985748,
         110.20, 34.55
       ]),
       // 宽度
       width: 2,
       // 线的颜色
       material: Cesium.Color.WHITE,
       // 线的顺序,仅当`clampToGround`为true并且支持地形上的折线时才有效。
       zIndex: 10,
       // 显示在距相机的距离处的属性,多少区间内是可以显示的
       distanceDisplayCondition: new Cesium.DistanceDisplayCondition(0, 1500),
       // 是否显示
       show: true
     }
   });

(三)面

viewer.entities.add({
   
   
      polygon: {
   
   
        // 获取指定属性(positions,holes(图形内需要挖空的区域))
        hierarchy: {
   
   
          positions: Cesium.Cartesian3.fromDegreesArray([
            120.9677706, 30.7985748,
            110.20, 34.55,
            120.20, 50.55
          ]),
          holes: [{
   
   
            positions: Cesium.Cartesian3.fromDegreesArray([
              119, 32,
              115, 34,
              119, 40
            ])
          }]
        },
        // 边框
        outline: true,
        // 边框颜色
        outlineColor: Cesium.Color.WHITE,
        // 边框尺寸
        outlineWidth: 2,
        // 填充的颜色,withAlpha透明度
        material: Cesium.Color.GREEN.withAlpha(0.5),
        // 是否被提供的材质填充
        fill: true,
        // 恒定高度
        height: 5000,
        // 显示在距相机的距离处的属性,多少区间内是可以显示的
        distanceDisplayCondition: new Cesium.DistanceDisplayCondition(1000, 10000000),
        // 是否显示
        show: true,
        // 顺序,仅当`clampToGround`为true并且支持地形上的折线时才有效。
        zIndex: 10
      }
    });

(四)文字

viewer.entities.add({
   
   
      position: Cesium.Cartesian3.fromDegrees(120, 30, 5),
      // 点
      point: {
   
   
        color: Cesium.Color.RED, // 点位颜色
        pixelSize: 10 // 像素点大小
      },
      // 文字
      label: {
   
   
        // 文本。支持显式换行符“ \ n”
        text: '测试名称',
        // 字体样式,以CSS语法指定字体
        font: '14pt Source Han Sans CN',
        // 字体颜色
        fillColor: Cesium.Color.BLACK,
        // 背景颜色
        backgroundColor: Cesium.Color.AQUA,
        // 是否显示背景颜色
        showBackground: true,
        // 字体边框
        outline: true,
        // 字体边框颜色
        outlineColor: Cesium.Color.WHITE,
        // 字体边框尺寸
        outlineWidth: 10,
        // 应用于图像的统一比例。比例大于会1.0放大标签,而比例小于会1.0缩小标签。
        scale: 1.0,
        // 设置样式:FILL:填写标签的文本,但不要勾勒轮廓;OUTLINE:概述标签的文本,但不要填写;FILL_AND_OUTLINE:填写并概述标签文本。
        style: Cesium.LabelStyle.FILL_AND_OUTLINE,
        // 相对于坐标的水平位置
        verticalOrigin: Cesium.VerticalOrigin.CENTER,
        // 相对于坐标的水平位置
        horizontalOrigin: Cesium.HorizontalOrigin.LEFT,
        // 该属性指定标签在屏幕空间中距此标签原点的像素偏移量
        pixelOffset: new Cesium.Cartesian2(10, 0),
        // 显示在距相机的距离处的属性,多少区间内是可以显示的
        distanceDisplayCondition: new Cesium.DistanceDisplayCondition(0, 1500),
        // 是否显示
        show: true
      }
    });

(五)广告牌(图片)

viewer.entities.add({
   
   
  position: Cesium.Cartesian3.fromDegrees(110.20, 34.55, 2.61),
  billboard: {
   
   
    // 图像地址,URI或Canvas的属性
    image: '/location.png',
    // 设置颜色和透明度
    color: Cesium.Color.WHITE.withAlpha(0.8),
    // 高度(以像素为单位)
    height: 50,
    // 宽度(以像素为单位)
    width: 50,
    // 逆时针旋转
    rotation: 20,
    // 大小是否以米为单位
    sizeInMeters: false,
    // 相对于坐标的垂直位置
    verticalOrigin: Cesium.VerticalOrigin.CENTER,
    // 相对于坐标的水平位置
    horizontalOrigin: Cesium.HorizontalOrigin.LEFT,
    // 该属性指定标签在屏幕空间中距此标签原点的像素偏移量
    pixelOffset: new Cesium.Cartesian2(10, 0),
    // 应用于图像的统一比例。比例大于会1.0放大标签,而比例小于会1.0缩小标签。
    scale: 1.0,
    // 显示在距相机的距离处的属性,多少区间内是可以显示的
    distanceDisplayCondition: new Cesium.DistanceDisplayCondition(0, 1500),
    // 是否显示
    show: true
  }
});

(六)模型

viewer.entities.add({
   
   
      // 设置方向
      orientation: orientation,
      position: Cesium.Cartesian3.fromDegrees(120, 30, 10000),
      model: {
   
   
        // 引入模型
        uri: '/SampleData/models/CesiumAir/Cesium_Air.glb',
        // 模型的近似最小像素大小,而不考虑缩放。这可以用来确保即使观看者缩小也可以看到模型。如果为0.0,则不强制使用最小大小
        minimumPixelSize: 1280,
        // 模型的颜色(与模型的渲染颜色混合的属性)
        color: Cesium.Color.WHITE.withAlpha(1),
        // 模型的最大比例大小
        maximumScale: 20000,
        // 设置模型轮廓(边框)颜色
        silhouetteColor: Cesium.Color.BLACK,
        // 设置模型轮廓(边框)大小
        silhouetteSize: 2,
        // 是否执行模型动画
        runAnimations: true,
        // 应用于图像的统一比例。比例大于会1.0放大标签,而比例小于会1.0缩小标签。
        scale: 1.0,
        // 显示在距相机的距离处的属性,多少区间内是可以显示的
        distanceDisplayCondition: new Cesium.DistanceDisplayCondition(0, 1500),
        // 是否显示
        show: true
      }
    });

如出现地形遮挡问题,可关闭cesium深度检测:viewer.scene.globe.depthTestAgainstTerrain = false;

五、添加primitive

(一)点

const pointsDataSource = viewer.scene.primitives.add(new Cesium.PointPrimitiveCollection())
// 创建点
for (const index in points) {
   
   
     pointsDataSource.add({
   
   
          pixelSize: 10,
          color: Cesium.Color.fromCssColorString('#fff'),
          position: Cesium.Cartesian3.fromDegrees(item[0], item[1], item[2]),
        });
}
// 销毁点
pointsDataSource?.removeAll();

(二)线

const newArr1 = []; let newArr2 = [];
// eslint-disable-next-line array-callback-return
points.map((item) => {
   
   
  newArr1.push(item[0]);
  newArr1.push(item[1])
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值