이번 시간에는 Cesium JS를 활용한 비행 애니메이션을 활용하도록 하겠습니다.

 

결과를 먼저 확인해보세요.

서비스바로가기

 

1.  애니메이션 기능의 비행시간과 항공기가 비행할 비행구역을 생성하기위한 소스코드입니다.

 
viewer.scene.globe.enableLighting = true;
 
viewer.scene.globe.depthTestAgainstTerrain = true//지형 생성 관련
 
Cesium.Math.setRandomNumberSeed(3);  
 
// 시작, 종료 날짜 설정
var start = Cesium.JulianDate.fromDate(new Date(20192810)); 
var stop = Cesium.JulianDate.addSeconds(start, 360new Cesium.JulianDate());
 
// viewer 작동 시간 확인
viewer.clock.startTime = start.clone();
viewer.clock.stopTime = stop.clone();
viewer.clock.currentTime = start.clone();
viewer.clock.clockRange = Cesium.ClockRange.LOOP_STOP; // loop 종료
viewer.clock.multiplier = 10;
 
// 항공기 비행 구역 설정 
function computeCircularFlight(lon, lat, radius){
    var property = new Cesium.SampledPositionProperty();
     
    for(var i=0; i<=360; i+=45){
        var radians = Cesium.Math.toRadians(i); // 범위 설정
        var time = Cesium.JulianDate.addSeconds(start, i, new Cesium.JulianDate()); // 시간 설정
        var position = Cesium.Cartesian3.fromDegrees(lon + (radius * 1.5 * Math.cos(radians)), // 비행구역 위치 설정 
                       lat + (radius * Math.sin(radians)),
                       Cesium.Math.nextRandomNumber() * 500+1000);
        property.addSample(time, position);
        // 비행구역 구분점 표시
        viewer.entities.add({
            position : position, // position = 비행구역 위치
            point : {
                pixelSize : 8,
                color : Cesium.Color.YELLOW,
                outlinecolor : Cesium.Color.YELLOW,
                outlineWidth : 3
            }
        });
    }
    return property;
}
cs

* for문 내에 비행 시간과 비행 구역을 설정하는 계산은 매우 복잡합니다. Cesium Document를 통해 자세한 내용을 살펴보세요.

 

2. 항공기를 생성하고 비행구역의 색상 및 두께 등의 세부 설정을 합니다.

 
// 항공기 생성
var entity = viewer.entities.add({
    availability : new Cesium.TimeIntervalCollection([new Cesium.TimeInterval({
        start : start,
        stop : stop
    })]),
    
    position : position, 
    
    orientation : new Cesium.VelocityOrientationProperty(position),
    model : {
        uri : "js/Cesium-1.53/Apps/SampleData/models/CesiumAir/Cesium_Air.gltf",
        minimumPixelSize : 64
    },
    
    path : {
        resolution : 1,
        material : new Cesium.PolylineGlowMaterialProperty({
            glowPower : 0.1,
            color : Cesium.Color.YELLOW
        }),
        width : 10
    }
});
cs

 

3. <body>태그 내에 항공기 관점을 변경하기 위한 버튼과 onclick 이벤트를 구현합니다.

 
<body>
<div id="toolbar">    
    <h5>항공기 관점 변경하기</h5>
    <div id="camcontrol">
        <input type="button" class="cesium-button" value="상공에서 바라보기" onclick="lookSkyview();">
        <input type="button" class="cesium-button" value="측면에서 바라보기" onclick="lookSideview();">
        <input type="button" class="cesium-button" value="항공기 바라보기" onclick="lookAirport();">
    </div>        
</div>
</body>
cs

 

4. onclick 이벤트를 구현할 function들을 작성합니다.

 
// ====================== 카메라 시점 변경 부분========================== 
// 상공에서 바라보기
function lookSkyview(){
    var transform = Cesium.Transforms.eastNorthUpToFixedFrame(Cesium.Cartesian3.fromDegrees(126.92440337.524624));
    var camera = viewer.camera;
    
    camera.constraintedAxis = Cesium.Cartesian3.UNIT_Z;
    camera.lookAtTransform(transform, new Cesium.Cartesian3(-10000.0-10000.025000.0));
    
    viewer.trackedEntity = undefined;
    viewer.zoomTo(viewer.entities, new Cesium.HeadingPitchRange(0, Cesium.Math.toRadians(-90)));
}
 
// 측면에서 바라보기
function lookSideview(){    
    viewer.trackedEntity = undefined;
    viewer.zoomTo(viewer.entities, new Cesium.HeadingPitchRange(Cesium.Math.toRadians(-90),
    Cesium.Math.toRadians(-15), 8000));
}
 
// 항공기 바라보기
function lookAirport(){
    viewer.trackedEntity = entity;
}
cs

 

전체 소스코드는 다음과 같습니다.

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
<!DOCTYPE>
<html>
<meta charset="UTF-8">
<head>
<script src="js/Cesium-1.53/Build/Cesium/Cesium.js"></script>
<link href="js/Cesium-1.53/Build/Cesium/Widgets/widgets.css" rel="stylesheet">
 
<style>
    #toolbar{
        padding : 1px;
        border-redius : 4px;
    }
    #toolbar input{
        vertical-align : middle;
        padding-top : 2px;
        padding-bottom : 2px;
    }
    #toolbar .header{
        font-weight : bold;
    }
</style>
 
<div id="cesiumContainer" style="width:auto; height:620px;"></div>
<script>
var extent = Cesium.Rectangle.fromDegrees(117.89628431.499028139.59738043.311528);
 
Cesium.Camera.DEFAULT_VIEW_RECTANGLE = extent;
Cesium.Camera.DEFAULT_VIEW_FACTOR = 0;
 
var viewer = new Cesium.Viewer('cesiumContainer',{
    timeline : false,
    selectionIndicator : false,
    navigationHelpButton : false,
    infoBox : false,
    navigationInstructionInitiallyVisible : false,
    baseLayerPicker : true,
    shouldAnimate : true//animation 가능 
    terrainProvider : Cesium.createWorldTerrain() // 기본 지도를 지형지도로 셋팅
});    
 
viewer.scene.globe.enableLighting = true;
 
viewer.scene.globe.depthTestAgainstTerrain = true//지형 생성 관련
 
Cesium.Math.setRandomNumberSeed(3);  
 
// 시작, 종료 날짜 설정
var start = Cesium.JulianDate.fromDate(new Date(20192810)); 
var stop = Cesium.JulianDate.addSeconds(start, 360new Cesium.JulianDate());
 
// viewer 작동 시간 확인
viewer.clock.startTime = start.clone();
viewer.clock.stopTime = stop.clone();
viewer.clock.currentTime = start.clone();
viewer.clock.clockRange = Cesium.ClockRange.LOOP_STOP; // loop 종료
viewer.clock.multiplier = 10;
 
// 항공기 비행 구역 설정 
function computeCircularFlight(lon, lat, radius){
    var property = new Cesium.SampledPositionProperty();
     
    for(var i=0; i<=360; i+=45){
        var radians = Cesium.Math.toRadians(i); // 범위 설정
        var time = Cesium.JulianDate.addSeconds(start, i, new Cesium.JulianDate()); // 시간 설정
        var position = Cesium.Cartesian3.fromDegrees(lon + (radius * 1.5 * Math.cos(radians)), // 비행구역 위치 설정 
                       lat + (radius * Math.sin(radians)),
                       Cesium.Math.nextRandomNumber() * 500+1000);
        property.addSample(time, position);
        // 비행구역 구분점 표시
        viewer.entities.add({
            position : position, // position = 비행구역 위치
            point : {
                pixelSize : 8,
                color : Cesium.Color.YELLOW,
                outlinecolor : Cesium.Color.YELLOW,
                outlineWidth : 3
            }
        });
    }
    return property;
}
 
var position = computeCircularFlight(126.92440337.5246240.03); // 비행구역 중간점 설정
 
var entity = viewer.entities.add({availability : new Cesium.TimeIntervalCollection([new Cesium.TimeInterval({
        start : start,
        stop : stop
    })]),
    
    position : position, 
    
    orientation : new Cesium.VelocityOrientationProperty(position),
    model : {
        uri : "js/Cesium-1.53/Apps/SampleData/models/CesiumAir/Cesium_Air.gltf",
        minimumPixelSize : 64
    },
    
    path : {
        resolution : 1,
        material : new Cesium.PolylineGlowMaterialProperty({
            glowPower : 0.1,
            color : Cesium.Color.YELLOW
        }),
        width : 10
    }
});
 
// ====================== 카메라 시점 변경 부분========================== 
// 상공에서 바라보기
function lookSkyview(){
    var transform = Cesium.Transforms.eastNorthUpToFixedFrame(Cesium.Cartesian3.fromDegrees(126.92440337.524624));
    var camera = viewer.camera;
    
    camera.constraintedAxis = Cesium.Cartesian3.UNIT_Z;
    camera.lookAtTransform(transform, new Cesium.Cartesian3(-10000.0-10000.025000.0));
    
    viewer.trackedEntity = undefined;
    viewer.zoomTo(viewer.entities, new Cesium.HeadingPitchRange(0, Cesium.Math.toRadians(-90)));
}
 
// 측면에서 바라보기
function lookSideview(){    
    viewer.trackedEntity = undefined;
    viewer.zoomTo(viewer.entities, new Cesium.HeadingPitchRange(Cesium.Math.toRadians(-90),
    Cesium.Math.toRadians(-15), 8000));
}
 
// 항공기 바라보기
function lookAirport(){
    viewer.trackedEntity = entity;
}
 
</script>
</head>
<body>
<div id="toolbar">    
    <h5>항공기 관점 변경하기</h5>
    <div id="camcontrol">
        <input type="button" class="cesium-button" value="상공에서 바라보기" onclick="lookSkyview();">
        <input type="button" class="cesium-button" value="측면에서 바라보기" onclick="lookSideview();">
        <input type="button" class="cesium-button" value="항공기 바라보기" onclick="lookAirport();">
    </div>        
</div>
</body>
</html>
cs

 

소스코드 작성이 완료되었으니 실행시켜보겠습니다. (비행구역은 여의도 상공으로 지정하였습니다.)

1. 최초 실행 시의 모습입니다. 

화면 좌하단에 애니메이션 기능이 추가되었으며 각 버튼을 통해 실행, 중지가 가능합니다.  

또한 애니메이션 사이드 부분 화살표를 활용하여 항공기의 속도를 조절할 수 있습니다.

 

2. 상공에서 바라본 모습입니다.

 

3. 측면에서 바라 본 모습입니다.

 

4. 항공기를 바라 본 모습입니다.

 

+ Recent posts