当前位置:   article > 正文

cesium学习笔记(问题记录)——(二)_cesium雷达扫描效果

cesium雷达扫描效果

一、cesium雷达效果

添加雷达扫描线代码封装,通过PostProcessStage实现:

 /*
          添加雷达扫描线
          viewer
          cartographicCenter 扫描中心
          radius  半径 米
          scanColor 扫描颜色
          duration 持续时间 毫秒
        */
        function addRadarScanPostStage(viewer, cartographicCenter, radius, scanColor, duration) {
            var _Cartesian3Center = Cesium.Cartographic.toCartesian(cartographicCenter);
            var _Cartesian4Center = new Cesium.Cartesian4(_Cartesian3Center.x, _Cartesian3Center.y, _Cartesian3Center.z, 1);

            var _CartographicCenter1 = new Cesium.Cartographic(cartographicCenter.longitude, cartographicCenter.latitude, cartographicCenter.height + 500);
            var _Cartesian3Center1 = Cesium.Cartographic.toCartesian(_CartographicCenter1);
            var _Cartesian4Center1 = new Cesium.Cartesian4(_Cartesian3Center1.x, _Cartesian3Center1.y, _Cartesian3Center1.z, 1);

            var _CartographicCenter2 = new Cesium.Cartographic(cartographicCenter.longitude + Cesium.Math.toRadians(0.001), cartographicCenter.latitude, cartographicCenter.height);
            var _Cartesian3Center2 = Cesium.Cartographic.toCartesian(_CartographicCenter2);
            var _Cartesian4Center2 = new Cesium.Cartesian4(_Cartesian3Center2.x, _Cartesian3Center2.y, _Cartesian3Center2.z, 1);
            var _RotateQ = new Cesium.Quaternion();
            var _RotateM = new Cesium.Matrix3();

            var _time = (new Date()).getTime();

            var _scratchCartesian4Center = new Cesium.Cartesian4();
            var _scratchCartesian4Center1 = new Cesium.Cartesian4();
            var _scratchCartesian4Center2 = new Cesium.Cartesian4();
            var _scratchCartesian3Normal = new Cesium.Cartesian3();
            var _scratchCartesian3Normal1 = new Cesium.Cartesian3();

            var ScanPostStage = new Cesium.PostProcessStage({
                // fragmentShader: getRadarScanShader(), //有外圈的
                fragmentShader: getRadarScan(), // 无外圈
                uniforms: {
                    u_scanCenterEC: function () {
                        return Cesium.Matrix4.multiplyByVector(viewer.camera._viewMatrix, _Cartesian4Center, _scratchCartesian4Center);
                    },
                    u_scanPlaneNormalEC: function () {
                        var temp = Cesium.Matrix4.multiplyByVector(viewer.camera._viewMatrix, _Cartesian4Center, _scratchCartesian4Center);
                        var temp1 = Cesium.Matrix4.multiplyByVector(viewer.camera._viewMatrix, _Cartesian4Center1, _scratchCartesian4Center1);
                        _scratchCartesian3Normal.x = temp1.x - temp.x;
                        _scratchCartesian3Normal.y = temp1.y - temp.y;
                        _scratchCartesian3Normal.z = temp1.z - temp.z;

                        Cesium.Cartesian3.normalize(_scratchCartesian3Normal, _scratchCartesian3Normal);
                        return _scratchCartesian3Normal;
                    },
                    u_radius: radius,
                    u_scanLineNormalEC: function () {
                        var temp = Cesium.Matrix4.multiplyByVector(viewer.camera._viewMatrix, _Cartesian4Center, _scratchCartesian4Center);
                        var temp1 = Cesium.Matrix4.multiplyByVector(viewer.camera._viewMatrix, _Cartesian4Center1, _scratchCartesian4Center1);
                        var temp2 = Cesium.Matrix4.multiplyByVector(viewer.camera._viewMatrix, _Cartesian4Center2, _scratchCartesian4Center2);

                        _scratchCartesian3Normal.x = temp1.x - temp.x;
                        _scratchCartesian3Normal.y = temp1.y - temp.y;
                        _scratchCartesian3Normal.z = temp1.z - temp.z;

                        Cesium.Cartesian3.normalize(_scratchCartesian3Normal, _scratchCartesian3Normal);

                        _scratchCartesian3Normal1.x = temp2.x - temp.x;
                        _scratchCartesian3Normal1.y = temp2.y - temp.y;
                        _scratchCartesian3Normal1.z = temp2.z - temp.z;

                        var tempTime = (((new Date()).getTime() - _time) % duration) / duration;
                        Cesium.Quaternion.fromAxisAngle(_scratchCartesian3Normal, tempTime * Cesium.Math.PI * 2, _RotateQ);
                        Cesium.Matrix3.fromQuaternion(_RotateQ, _RotateM);
                        Cesium.Matrix3.multiplyByVector(_RotateM, _scratchCartesian3Normal1, _scratchCartesian3Normal1);
                        Cesium.Cartesian3.normalize(_scratchCartesian3Normal1, _scratchCartesian3Normal1);
                        return _scratchCartesian3Normal1;
                    },
                    u_scanColor: scanColor
                }
            });
            viewer.scene.postProcessStages.add(ScanPostStage);

            return ScanPostStage;
        }

//雷达扫描线效果Shader
        function getRadarScanShader() {
            var scanSegmentShader =
                "uniform sampler2D colorTexture;\n" +
                "uniform sampler2D depthTexture;\n" +
                "varying vec2 v_textureCoordinates;\n" +
                "uniform vec4 u_scanCenterEC;\n" +
                "uniform vec3 u_scanPlaneNormalEC;\n" +
                "uniform vec3 u_scanLineNormalEC;\n" +
                "uniform float u_radius;\n" +
                "uniform vec4 u_scanColor;\n" +

                "vec4 toEye(in vec2 uv, in float depth)\n" +
                " {\n" +
                " vec2 xy = vec2((uv.x * 2.0 - 1.0),(uv.y * 2.0 - 1.0));\n" +
                " vec4 posInCamera =czm_inverseProjection * vec4(xy, depth, 1.0);\n" +
                " posInCamera =posInCamera / posInCamera.w;\n" +
                " return posInCamera;\n" +
                " }\n" +

                "bool isPointOnLineRight(in vec3 ptOnLine, in vec3 lineNormal, in vec3 testPt)\n" +
                "{\n" +
                "vec3 v01 = testPt - ptOnLine;\n" +
                "normalize(v01);\n" +
                "vec3 temp = cross(v01, lineNormal);\n" +
                "float d = dot(temp, u_scanPlaneNormalEC);\n" +
                "return d > 0.5;\n" +
                "}\n" +

                "vec3 pointProjectOnPlane(in vec3 planeNormal, in vec3 planeOrigin, in vec3 point)\n" +
                "{\n" +
                "vec3 v01 = point -planeOrigin;\n" +
                "float d = dot(planeNormal, v01) ;\n" +
                "return (point - planeNormal * d);\n" +
                "}\n" +

                "float distancePointToLine(in vec3 ptOnLine, in vec3 lineNormal, in vec3 testPt)\n" +
                "{\n" +
                "vec3 tempPt = pointProjectOnPlane(lineNormal, ptOnLine, testPt);\n" +
                "return length(tempPt - ptOnLine);\n" +
                "}\n" +

                "float getDepth(in vec4 depth)\n" +
                "{\n" +
                "float z_window = czm_unpackDepth(depth);\n" +
                "z_window = czm_reverseLogDepth(z_window);\n" +
                "float n_range = czm_depthRange.near;\n" +
                "float f_range = czm_depthRange.far;\n" +
                "return (2.0 * z_window - n_range - f_range) / (f_range - n_range);\n" +
                "}\n" +

                "void main()\n" +
                "{\n" +
                "gl_FragColor = texture2D(colorTexture, v_textureCoordinates);\n" +
                "float depth = getDepth( texture2D(depthTexture, v_textureCoordinates));\n" +
                "vec4 viewPos = toEye(v_textureCoordinates, depth);\n" +
                "vec3 prjOnPlane = pointProjectOnPlane(u_scanPlaneNormalEC.xyz, u_scanCenterEC.xyz, viewPos.xyz);\n" +
                "float dis = length(prjOnPlane.xyz - u_scanCenterEC.xyz);\n" +
                "float twou_radius = u_radius * 2.0;\n" +
                "if(dis < u_radius)\n" +
                "{\n" +
                "float f0 = 1.0 -abs(u_radius - dis) / u_radius;\n" +
                "f0 = pow(f0, 64.0);\n" +
                "vec3 lineEndPt = vec3(u_scanCenterEC.xyz) + u_scanLineNormalEC * u_radius;\n" +
                "float f = 0.0;\n" +
                "if(isPointOnLineRight(u_scanCenterEC.xyz, u_scanLineNormalEC.xyz, prjOnPlane.xyz))\n" +
                "{\n" +
                "float dis1= length(prjOnPlane.xyz - lineEndPt);\n" +
                "f = abs(twou_radius -dis1) / twou_radius;\n" +
                "f = pow(f, 3.0);\n" +
                "}\n" +
                "gl_FragColor = mix(gl_FragColor, u_scanColor, f + f0);\n" +
                "}\n" +
                "}\n";
            return scanSegmentShader;
        }

//无外圈
function getRadarScan(){
var radarScan = "uniform sampler2D colorTexture;\n\
                uniform sampler2D depthTexture;\n\
                varying vec2 v_textureCoordinates;\n\
                uniform vec4 u_scanCenterEC;\n\
                uniform vec3 u_scanPlaneNormalEC;\n\
                uniform vec3 u_scanLineNormalEC;\n\
                uniform float u_radius;\n\
                uniform vec4 u_scanColor;\n\
                \n\
                vec4 toEye(in vec2 uv, in float depth){\n\
                vec2 xy = vec2((uv.x * 2.0 - 1.0),(uv.y * 2.0 - 1.0));\n\
                vec4 posInCamera =czm_inverseProjection * vec4(xy, depth, 1.0);\n\
                posInCamera =posInCamera / posInCamera.w;\n\
                return posInCamera;\n\
                }\n\
                \n\
                bool isPointOnLineRight(in vec3 ptOnLine, in vec3 lineNormal, in vec3 testPt){\n\
                vec3 v01 = testPt - ptOnLine;\n\
                normalize(v01);\n\
                vec3 temp = cross(v01, lineNormal);\n\
                float d = dot(temp, u_scanPlaneNormalEC);\n\
                return d > 0.5;\n\
                }\n\
                \n\
                vec3 pointProjectOnPlane(in vec3 planeNormal, in vec3 planeOrigin, in vec3 point){\n\
                vec3 v01 = point -planeOrigin;\n\
                float d = dot(planeNormal, v01) ;\n\
                return (point - planeNormal * d);\n\
                }\n\
                \n\
                float distancePointToLine(in vec3 ptOnLine, in vec3 lineNormal, in vec3 testPt){\n\
                vec3 tempPt = pointProjectOnPlane(lineNormal, ptOnLine, testPt);\n\
                return length(tempPt - ptOnLine);\n\
                }\n\
                \n\
                float getDepth(in vec4 depth){\n\
                float z_window = czm_unpackDepth(depth);\n\
                z_window = czm_reverseLogDepth(z_window);\n\
                float n_range = czm_depthRange.near;\n\
                float f_range = czm_depthRange.far;\n\
                return (2.0 * z_window - n_range - f_range) / (f_range - n_range);\n\
                }\n\
                \n\
                void main(){\n\
                gl_FragColor = texture2D(colorTexture, v_textureCoordinates);\n\
                float depth = getDepth( texture2D(depthTexture, v_textureCoordinates));\n\
                vec4 viewPos = toEye(v_textureCoordinates, depth);\n\
                vec3 prjOnPlane = pointProjectOnPlane(u_scanPlaneNormalEC.xyz, u_scanCenterEC.xyz, viewPos.xyz);\n\
                float dis = length(prjOnPlane.xyz - u_scanCenterEC.xyz);\n\
                float twou_radius = u_radius * 2.0;\n\
                if(dis < u_radius){\n\
                    float f0 = 1.0 -abs(u_radius - dis) / u_radius;\n\
                    f0 = pow(f0, 64.0);\n\
                    vec3 lineEndPt = vec3(u_scanCenterEC.xyz) + u_scanLineNormalEC * u_radius;\n\
                    float f = 0.0;\n\
                    if(isPointOnLineRight(u_scanCenterEC.xyz, u_scanLineNormalEC.xyz, prjOnPlane.xyz)){\n\
                        float dis1= length(prjOnPlane.xyz - lineEndPt);\n\
                        f = abs(twou_radius -dis1) / twou_radius;\n\
                        f = pow(f, 5.0);\n\
                    }\n\
                    gl_FragColor = mix(gl_FragColor, u_scanColor, f);\n\
                    }\n\
                }\n\
                ";
return radarScan ;
        
}

  • 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
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134
  • 135
  • 136
  • 137
  • 138
  • 139
  • 140
  • 141
  • 142
  • 143
  • 144
  • 145
  • 146
  • 147
  • 148
  • 149
  • 150
  • 151
  • 152
  • 153
  • 154
  • 155
  • 156
  • 157
  • 158
  • 159
  • 160
  • 161
  • 162
  • 163
  • 164
  • 165
  • 166
  • 167
  • 168
  • 169
  • 170
  • 171
  • 172
  • 173
  • 174
  • 175
  • 176
  • 177
  • 178
  • 179
  • 180
  • 181
  • 182
  • 183
  • 184
  • 185
  • 186
  • 187
  • 188
  • 189
  • 190
  • 191
  • 192
  • 193
  • 194
  • 195
  • 196
  • 197
  • 198
  • 199
  • 200
  • 201
  • 202
  • 203
  • 204
  • 205
  • 206
  • 207
  • 208
  • 209
  • 210
  • 211
  • 212
  • 213
  • 214
  • 215
  • 216
  • 217
  • 218
  • 219
  • 220
  • 221
  • 222
  • 223
  • 224
  • 225

代码调用

var cartographicCenter = new Cesium.Cartographic(Cesium.Math.toRadians(117.270739), Cesium.Math.toRadians(31.84309), 32);
var scanColor = new Cesium.Color(1.0, 0.0, 0.0, 1);
 lastStage = addRadarScanPostStage(viewer, cartographicCenter, 1000, scanColor, 3000);
  • 1
  • 2
  • 3

二、billboard高亮

通过修改color属性来进行高亮
在这里插入图片描述

三、调整倾斜摄影高度

倾斜摄影模型不贴地问题处理

(一)调整offset参数中的高度

 tileset.readyPromise.then(function (tileset,h) {
    var cartographic = Cesium.Cartographic.fromCartesian(
        tileset.boundingSphere.center
    );
    var surface = Cesium.Cartesian3.fromRadians(
        cartographic.longitude,
        cartographic.latitude,
        0.0
    );
    var offset = Cesium.Cartesian3.fromRadians(
        cartographic.longitude,
        cartographic.latitude,
        h    //填高度差值,如未知,可通过点击获取位置信息中的高度
    );
    var translation = Cesium.Cartesian3.subtract(
        offset,
        surface,
        new Cesium.Cartesian3()
    );
    tileset.modelMatrix = Cesium.Matrix4.fromTranslation(translation);
    viewer.scene.primitives.add(tileset);
    viewer.flyTo(tileset)

}).otherwise(function (error) {
    console.log(error);
})
  • 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

(二)获取模型中心点高程

const tileset=viewer.scene.groundPrimitives.add(new Cesium.Cesium3DTileset({
    url: url,//此处填写tileset url地址
}));
tileset.readyPromise.then(function (tileset) {               
    const boundingSphere = tileset.boundingSphere;
    const cartographic = Cesium.Cartographic.fromCartesian(boundingSphere.center);//获取到倾斜数据中心点的经纬度坐标(弧度)
    const surface = Cesium.Cartesian3.fromRadians(cartographic.longitude, cartographic.latitude, 0.0);//倾斜数据中心点的笛卡尔坐标      
     const positions = [Cesium.Cartographic.fromDegrees(cartographic.longitude,cartographic.latitude)];
     const promise = Cesium.sampleTerrainMostDetailed(terrainProvider, positions);//其中terrainProvider是当前场景使用的高程Provider
    promise.then((updatedPositions) => {
       const terrainHeight = updatedPositions[0].height;//高程
       const offset=Cesium.Cartesian3.fromRadians(cartographic.longitude, cartographic.latitude, terrainHeight);//带高程的新笛卡尔坐标
       const translation = Cesium.Cartesian3.subtract(offset, surface, new Cesium.Cartesian3());//做差得到变换矩阵
       tileset.modelMatrix = Cesium.Matrix4.fromTranslation(translation);
  })
})
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16

四、primitive方式添加多边形贴地形或模型

var primitive = new Cesium.GroundPrimitive({
  geometryInstances: new Cesium.GeometryInstance({
    geometry: polygon
  }),
  appearance: new Cesium.EllipsoidSurfaceAppearance({
    aboveGround: true
  }),
  classificationType : Cesium.ClassificationType.BOTH,	// 支持类型: 地形、3DTile、或者在地面上
  show: true
});
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

classificationType 参数:

Cesium.ClassificationType.BOTH 贴于所有地物上
Cesium.ClassificationType.TERRAIN 只贴于地形上
Cesium.ClassificationType.CESIUM_3D_TILE 只贴于3dtile上
  • 1
  • 2
  • 3

五、entity方式添加多边形

<!DOCTYPE html>
<html lang="ch-en">
<head>
    <meta charset="UTF-8">
    <title></title>
    <link rel="stylesheet" href="./js/Cesium-1.72/Build/Cesium/Widgets/widgets.css">
    <style>
        #map3d {
            height: 1000px;
            width: 1000px;
            margin: 0 auto;
        }
    </style>
</head>
<body>
<div id="map3d"></div>
</body>
<script src="./js/Cesium-1.72/Build/Cesium/Cesium.js"></script>
<script src="./js/jQuery.js"></script>
<script>
  viewer = new Cesium.Viewer('map3d', {
    selectionIndicator: false,
    animation: false,
    baseLayerPicker: false,
    timeline: false,
    sceneModePicker: false,
    navigationHelpButton: false,
    fullscreenButton: false,
    imageryProvider: new Cesium.WebMapTileServiceImageryProvider({
      url: 'http://t0.tianditu.gov.cn/img_w/wmts?tk=7fdca056b488529020b96dd0a6891579',
      layer: 'img',
      style: 'default',
      tileMatrixSetID: 'w',
      format: 'tiles',
      tileHeight: 0,
      maximumLevel: 18
    }),
  });
  const json = {
   "type": "Polygon",
   "coordinates": [[[106.818340748, 35.345186594], [106.912227457, 35.857950428], [107.235357796, 35.9277981500001], [107.730486478, 36.022622105], [107.85655614, 35.8806908460001], [107.822121228, 35.5285600620001], [107.584770259, 35.2284864530001], [107.376631529, 35.1572428380001], [107.022823644, 35.1807053140001], [106.988349662, 35.2733902210001], [106.818340748, 35.345186594]]]
}
let data = []
json.coordinates[0].forEach(item => {
  data.push(Cesium.Cartesian3.fromDegrees(item[0], item[1]))
})
let entity = new Cesium.Entity({
  id: `${new Date().getTime()}`,
  name: "线几何对象",
  show: true,
  polygon: {
    hierarchy: new Cesium.PolygonHierarchy(data),
    material: Cesium.Color.RED.withAlpha(0.65),
    perPositionHeight: true,
  }
});
viewer.entities.add(entity);
</script>
</html>
  • 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
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59

六、自定义HTML弹窗

实现思路部分:
(1)cesium 的点击事件 Cesium.ScreenSpaceEventType.LEFT_CLICK 监听左键单击鼠标事件获取当前位置坐标,然后根据当前笛卡尔坐标去确认气泡窗口div的显示位置;
(2)监听 cesium 的 postRender 每一帧变化的监听事件,该事件就是为了确认你在转动球体时,气泡只定位到当前位置,不会出现偏差,该事件每帧的移动时,重新对气泡进行重新定位,屏幕坐标到笛卡尔坐标的转换。

(一)左键鼠标单击监听事件

//获取当前点击的位置坐标
var handler = new Cesium.ScreenSpaceEventHandler(viewer.scene.canvas);
handler.setInputAction(function(movement) {
  /* var windowPosition = viewer.camera.getPickRay(movement.position);
  var cartesianCoordinates = viewer.scene.globe.pick(windowPosition, viewer.scene);
  var cartoCoordinates = viewer.scene.globe.ellipsoid.cartesianToCartographic(cartesianCoordinates); */
  var cartesian2 = viewer.camera.pickEllipsoid(movement.position, viewer.scene.globe.ellipsoid);
  var carto2 = viewer.scene.globe.ellipsoid.cartesianToCartographic(cartesian2);
  latitude = carto2.latitude * 180 / Math.PI;
  longitude = carto2.longitude * 180 / Math.PI;
  //alert("纬度:"+latitude+","+"经度:"+longitude);
  var cartesian = viewer.scene.pickPosition(movement.position);
  //弹窗 参数 
  var paramObj = {
  	id: 'trackPopUpContent',
    HTMLdiv: '<div class="leaflet-popup-content-wrapper" style="background:#FFF;">' +
       '<div id="trackPopUpLink" class="leaflet-popup-content" style="max-width:300px;max-height:500px"><h5>纬度:' +
       latitude + ',<br>经度:' + longitude + '</h5></div>' +
       '</div>', 
    Offset: {
      x: 0,
      y: 0
	},
    coordinate: cartesian, //笛卡尔坐标参数
    lineStyle: {
      Linewidth: 3,
      Lineheight: 25,
      Linebackground: '#409EFF'
    },
   	CircleStyle: {
      Circleradius: 8,
      Circlecolor: '#409EFF'
   	},
   	heighthidenum: 1000, //高度隐藏值
}
//固定弹窗 位置
PopupCoordinatePositioning(paramObj);
}, Cesium.ScreenSpaceEventType.LEFT_CLICK);
  • 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
  • 36
  • 37
  • 38

(二)地图每一帧变化的监听事件

viewer.scene.postRender.addEventListener(function() { // 每一帧都去计算气泡的正确位置
  if (Popups.length > 0) {
    for (var i = 0; i < Popups.length; i++) {
      var infoboxContainer = document.getElementById(Popups[i].PopupsID); //morphComplete
      if (infoboxContainer != null) {
        //var infoboxContainer = document.getElementById("bubble");//morphComplete
        if (Popups[i].scenePosition) {
          var canvasHeight = viewer.scene.canvas.height;
          var windowPosition = new Cesium.Cartesian2();
          Cesium.SceneTransforms.wgs84ToWindowCoordinates(viewer.scene, Popups[i].scenePosition, windowPosition);
          infoboxContainer.style.bottom = (canvasHeight - windowPosition.y + Popups[i].paramObj.Offset.y) + 'px';
          infoboxContainer.style.left = (windowPosition.x + -(infoboxContainer.scrollWidth / 2)) + 'px';
       	}
      }
  }
}
});
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17

七、计算模型的四元数,实现朝向调整

getQuaternion(positionEcf, velocityEcf) {
  // 1、计算站心到模型坐标系的旋转平移矩阵
  // 速度归一化
  let normal =  Cartesian3.normalize(velocityEcf, new  Cartesian3());
  // 计算模型坐标系的旋转矩阵
  let satRotationMatrix =  Transforms.rotationMatrixFromPositionVelocity(positionEcf, normal,  Ellipsoid.WGS84);
  // 模型坐标系到地固坐标系旋转平移矩阵
  let m =  Matrix4.fromRotationTranslation(satRotationMatrix, positionEcf);
  // 站心坐标系(东北天坐标系)到地固坐标系旋转平移矩阵
  var m1 =  Transforms.eastNorthUpToFixedFrame(positionEcf,  Ellipsoid.WGS84, new  Matrix4());
  // 站心到模型坐标系的旋转平移矩阵
  let m3 =  Matrix4.multiply( Matrix4.inverse(m1, new Matrix4()), m, new Matrix4());
  
  // 2、模型姿态旋转矩阵(根据实际需要)
  let h1 = 0, p1 = 0, r1 = 0;
  let postureHpr = new  HeadingPitchRoll( Math.toRadians(h1),  Math.toRadians(p1),  Math.toRadians(r1));
  let postureMatrix =  Matrix3.fromHeadingPitchRoll(postureHpr);

  // 3、模型朝向旋转矩阵
  let h2 = 0, p2 = -180, r2 = 0;
  let sHpr = new  HeadingPitchRoll( Math.toRadians(h2),  Math.toRadians(p2),  Math.toRadians(r2));
  let sMatrix =  Matrix3.fromHeadingPitchRoll(sensorHpr);
  
  // 4、最终的旋转矩阵
  let mat3 =  Matrix4.getMatrix3(m3, new  Matrix3());
  let finalMatrix =  Matrix3.multiply(mat3,postureMatrix,new  Matrix3());
  let finalMatrix1 =  Matrix3.multiply(finalMatrix, sMatrix, new  Matrix3())
  let quaternion1 =  Quaternion.fromRotationMatrix(finalMatrix1);
  let hpr =  HeadingPitchRoll.fromQuaternion(quaternion1);
  let q2 =  Transforms.headingPitchRollQuaternion(positionEcf,hpr);
  return q2;
}
  • 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

八、Cesium雷达追踪圆锥体

//添加圆锥体
addSpaceFollow() {
    this.viewer.entities.add({
        orientation: new Cesium.CallbackProperty(e => {
            let m = this.getModelMatrix(this.originPosition, this.targetPosition);
            let hpr = this.getHeadingPitchRoll(m);
            hpr.pitch = hpr.pitch + 3.14 / 2 + 3.14;
            return Cesium.Transforms.headingPitchRollQuaternion(this.originPosition, hpr);
        }, false),
        position: new Cesium.CallbackProperty(e => {
            return Cesium.Cartesian3.midpoint(this.originPosition, this.targetPosition, new Cesium.Cartesian3())
        }, false),
        cylinder: {
            length: new Cesium.CallbackProperty(e => {
                return Cesium.Cartesian3.distance(this.originPosition, this.targetPosition)
            }, false),
            topRadius: 15.0,
            bottomRadius: 0.0,
            material: Cesium.Color.RED.withAlpha(0.4),
        },
    });
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22

九、Cesium颜色相关

(一)cesium颜色

Cesium.Color.BLUE; // 蓝色
 
Cesium.Color.RED; // 红色
 
Cesium.Color.BLUE.withAlpha(0.5)// 添加透明度
  • 1
  • 2
  • 3
  • 4
  • 5

(二)rgba (a区间 0-1)

new Cesium.Color(0,0,255,1);  // 蓝色
 
new Cesium.Color(255,0,0,1);  //  红色
  • 1
  • 2
  • 3

(三)rgba (a区间 0-255)

Cesium.Color.fromBytes(0, 0, 255, 255); // 蓝色
 
Cesium.Color.fromBytes(255, 0, 0, 255); // 红色
  • 1
  • 2
  • 3

(四)Css颜色转Cesium颜色

Cesium.Color.fromCssColorString('#0000ff');  // 蓝色
Cesium.Color.fromCssColorString("rgba(0, 0, 255, 1)") // 蓝色
Cesium.Color.fromCssColorString('#ff0000');  // 红色
Cesium.Color.fromCssColorString("rgba(255, 0, 0, 1)");  // 红色
  • 1
  • 2
  • 3
  • 4

(五)随机颜色

Cesium.Color.fromRandom()
  • 1

十、modelMatrix计算

通过改变modelMatrix来实现primitive旋转== (ts写法)==

/**
 * primitive旋转,primitive实体
 * angle:旋转角度,number
 * rotateP:绕哪点旋转,cartesian3
 * type:旋转哪个轴,string类型,X,Y,Z
 */
export const rotatePrimitive = (datas:any) {
	const {primitive, angle, rotateP, type} = datas
    const baseMatrix = primitive.modelMatrix.clone(new Epgis3D.Matrix4());
    const enu = Epgis3D.Transforms.eastNorthUpToFixedFrame(rotateP);
    const inverseEnu = Epgis3D.Matrix4.inverse(enu, new Epgis3D.Matrix4());
    let rotation = undefined;
    if(type ==='X'){
    	rotation = Epgis3D.Matrix3.fromRotationX(Epgis3D.Math.toRadians(angle));
    }else if(type ==='Y'){
    	rotation = Epgis3D.Matrix3.fromRotationY(Epgis3D.Math.toRadians(angle));
    }else{
    	rotation = Epgis3D.Matrix3.fromRotationZ(Epgis3D.Math.toRadians(angle));
    }
    const matrix = Epgis3D.Matrix4.fromRotationTranslation(rotation);
    const scrach = new Epgis3D.Matrix4();
    let result = Epgis3D.Matrix4.multiply(inverseEnu, baseMatrix, scrach);
    result = Epgis3D.Matrix4.multiply(matrix, result, scrach);
    result = Epgis3D.Matrix4.multiply(enu, result, scrach);
    primitive.modelMatrix = result;
}
  • 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
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/盐析白兔/article/detail/564086
推荐阅读
相关标签
  

闽ICP备14008679号