Cesium JS에서 User Control 구현하기

이번시간에는 Cesium JS에서 User Controll을 구현하는 시간을 가져보도록 하겠습니다.

기능을 구현하여 라인과 폴리곤을 생성해보도록 하겠습니다.

 

먼저 결과 화면부터 확인하세요.

서비스바로가기

 

* 구현을 위해 작성한 소스코드입니다.

 
var handler = new Cesium.ScreenSpaceEventHandler(viewer.canvas);
 
handler.setInputAction(function(event) {
    var earthPosition = viewer.scene.pickPosition(event.position);
        
        if (Cesium.defined(earthPosition)) {
            if (activeShapePoints.length === 0) {
                floatingPoint = createPoint(earthPosition);
                activeShapePoints.push(earthPosition);
                var dynamicPositions = new Cesium.CallbackProperty(function () {
                    return activeShapePoints;
                }, false);
                activeShape = drawShape(dynamicPositions);
            }
            activeShapePoints.push(earthPosition);
            createPoint(earthPosition);
        }
    }, Cesium.ScreenSpaceEventType.LEFT_CLICK);
cs

EventHandler를 위한 handler 변수를 지정하였습니다.

마우스 좌클릭 이벤트를 통해 shape를 그릴 position을 지정합니다. 

 

 
handler.setInputAction(function(event) {
        if (Cesium.defined(floatingPoint)) {
            var newPosition = viewer.scene.pickPosition(event.endPosition);
            if (Cesium.defined(newPosition)) {
                floatingPoint.position.setValue(newPosition);
                activeShapePoints.pop();
                activeShapePoints.push(newPosition);
            }
        }
    }, Cesium.ScreenSpaceEventType.MOUSE_MOVE);
cs

mouse move 이벤트로 포인트와 포인트 간 shape이 생성될 수 있게끔 하였습니다.

 

 
handler.setInputAction(function(event) {
        terminateShape();
    }, Cesium.ScreenSpaceEventType.RIGHT_CLICK);
cs

마우스 우클릭 이벤트를 통해 shape 그리기를 종료하고 새로운 shape를 생성할 수 있게끔 하였습니다. 

 

shape 그리기를 종료하고 새로운 shape를 그리기 위해 아래와 같은 function을 구현하였습니다.

 
function terminateShape() {
        activeShapePoints.pop();
        drawShape(activeShapePoints);
        viewer.entities.remove(floatingPoint);
        viewer.entities.remove(activeShape);
        floatingPoint = undefined;
        activeShape = undefined;
        activeShapePoints = [];
    }
cs

생성되고있던 shape와 찍혀있던 point를 remove함수로 삭제하였습니다. 

 

아래는 포인트와 포인트를 통해 생성되는 Line과 Polygon에 대한 function 입니다.

 
// 포인트 생성 
    function createPoint(worldPosition) {
        var point = viewer.entities.add({
            position : worldPosition,
            point : {
                color : Cesium.Color.RED,
                pixelSize : 10,
                heightReference: Cesium.HeightReference.CLAMP_TO_GROUND
            }
        });
        return point;
    }
 
// 라인과 폴리곤 생성
    function drawShape(positionData) {
        var shape;
        if (drawingMode === 'line') {
            shape = viewer.entities.add({
                polyline : {
                    positions : positionData,
                    clampToGround : true,
                    width : 3
                }
            });
        }
        else if (drawingMode === 'polygon') {
            shape = viewer.entities.add({
                polygon: {
                    hierarchy: positionData,
                    material: new Cesium.ColorMaterialProperty(Cesium.Color.AQUA.withAlpha(0.15))
                }
            });
        }
        return shape;
    }
cs

포인트 생성을 위한 function 내에 point 옵션값 중 heightReference: Cesium.HeightReference.CLAMP_TO_GROUND 옵션은

포인트가 TerrainMap(지형형상 지도)를 인식하여 평면이 아닌 Terrain에 맞게 움직일 수 있게끔 하는 옵션입니다.

물론 라인과 폴리곤도 Terrain에 맞추어 그려집니다.

 

다음은 실행화면 입니다.

처음 실행화면 입니다. 서울 지역 중 평지와 산지가 공존하는 지역을 선정하였습니다.

 

라인과 폴리곤을 선택할 수 있는 select Box를 구현하였습니다.

각 option을 통해 라인과 폴리곤을 생성할 수 있습니다.

 

먼저 라인 그리기를 통해 라인을 그리는 모습입니다.

일직선으로 라인을 생성했지만 사진과 같이 선이 울퉁불퉁한 것을 느끼실 수 있을겁니다.

 

라인이 생성될 때 Terrain에 맞춰 생성되었기 때문이죠

 

폴리곤 또한 마찬가지 입니다.

폴리곤도 각 면이 울퉁불퉁하게 보입니다.

 

폴리곤도 Terrain에 맞춰 생성되었습니다.

 

shape를 만들었으니 삭제하는 기능도 있어야겠죠?

라인 그리기와 폴리곤 그리기로 shape를 생성한 후 화면정리를 선택하면 생성하였던 shape가 삭제됩니다.

select Box 안에 화면정리 기능도 넣어두었습니다.

 

화면정리를 선택하여 shape들을 삭제한 모습입니다.

 

* 전체 소스코드 내용은 다음과 같습니다.

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
<!DOCTYPE html>
<html lang='en'>
<meta charset="UTF-8">
<head>
<script src="js/Cesium-1.54/Build/Cesium/Cesium.js"></script>
<link href="js/Cesium-1.54/Build/Cesium/Widgets/widgets.css" rel="stylesheet">
<style>
    @import url(js/Cesium-1.54/Apps/Sandcastle/templates/bucket.css);
</style>
<div id="cesiumContainer" style="width:auto; height:700px"></div>
<script>
var extent = Cesium.Rectangle.fromDegrees(117.89628431.499028139.59738043.311528);
 
Cesium.Camera.DEFAULT_VIEW_RECTANGLE = extent;
Cesium.Camera.DEFAULT_VIEW_FACTOR = 0.7;
 
var viewer = new Cesium.Viewer('cesiumContainer',{
    timeline : false,
    animation : false,
    selectionIndicator : false,
    navigationHelpButton : false,
    infoBox : false,
    navigationInstructionsInitiallyVisible : false
});
 
var scene = viewer.scene;
// 위,경도 표출될 라벨의 옵션을 파라미터로 지정
var entity = viewer.entities.add({
    label : {
        show : true,
        showBackground : true,
        backgroundColor : Cesium.Color.BLACK,
        font : '25px sans-serif',
        horizontalOrigin : Cesium.HorizontalOrigin.LEFT,
        //verticalOrigin을 top으로 지정 
        verticalOrigin : Cesium.VerticalOrigin.TOP,
        //pixelOffset을 통해 label의 상세 위치를 지정 / Cartesian2 사용(x,y)
        pixelOffset : new Cesium.Cartesian2(150)
    }
});
// eventhandler 변수에 screenspacehandler를 담음
var eventhandler = new Cesium.ScreenSpaceEventHandler(scene.canvas);
// movement가 발생하면 위,경도 값을 표출 
eventhandler.setInputAction(function(movement){
    var cartesian = viewer.camera.pickEllipsoid(movement.endPosition, scene.globe.ellipsoid);
    if(cartesian){
        var cartographic = Cesium.Cartographic.fromCartesian(cartesian);
        var longitude = Cesium.Math.toDegrees(cartographic.longitude).toFixed(2);
        var latitude = Cesium.Math.toDegrees(cartographic.latitude).toFixed(2);
        
        entity.position = cartesian;
        entity.label.show = true;
        entity.label.text = '경도 : '+('' + longitude).slice(-7+ '\u00B0' + '\n위도 : '+('' + latitude).slice(-7+ '\u00B0';
    }else{
        entity.label.show = false;
    }
}, Cesium.ScreenSpaceEventType.MOUSE_MOVE);
</script>
</head>
<body>
</body>
</html>
cs

 

* 28 ~ 40행은 위,경도를 표출할 라벨의 옵션을 key : value 값, 파라미터로 지정한 부분입니다.

 
var entity = viewer.entities.add({
    label : {
        show : true,
        showBackground : true,
        backgroundColor : Cesium.Color.BLACK,
        font : '25px sans-serif',
        horizontalOrigin : Cesium.HorizontalOrigin.LEFT,
        //verticalOrigin을 top으로 지정 
        verticalOrigin : Cesium.VerticalOrigin.TOP,
        //pixelOffset을 통해 label의 상세 위치를 지정 / Cartesian2 사용(x,y)
        pixelOffset : new Cesium.Cartesian2(150)
    }
});
cs

 

* VerticalOrigin에 대한 설명입니다. (자세한 내용은 CesiumDocument를 참고하세요.)

각 포지션을 통해 라벨이 표출되는 위치를 조정할 수 있습니다.

 

* Cartesian2에 대한 설명입니다. (자세한 내용은 CesiumDocument를 참고하세요.)

Cartesian2는 2차원적 개념으로 x, y 값을 갖게됩니다.

 

* 44 ~ 57행은 MouseMove 이벤트를 활용하여 movement가 발생함에 따라 위,경도 값이 표출되게끔 하는 부분입니다.

 
eventhandler.setInputAction(function(movement){
    var cartesian = viewer.camera.pickEllipsoid(movement.endPosition, scene.globe.ellipsoid);
    if(cartesian){
        var cartographic = Cesium.Cartographic.fromCartesian(cartesian);
        var longitude = Cesium.Math.toDegrees(cartographic.longitude).toFixed(2);
        var latitude = Cesium.Math.toDegrees(cartographic.latitude).toFixed(2);
        
        entity.position = cartesian;
        entity.label.show = true;
        entity.label.text = '경도 : '+('' + longitude).slice(-7+ '\u00B0' + '\n위도 : '+('' + latitude).slice(-7+ '\u00B0';
    }else{
        entity.label.show = false;
    }
}, Cesium.ScreenSpaceEventType.MOUSE_MOVE);
cs

cartographic변수에 cartesian을 활용한 위,경도 값을 담아줍니다.

 

* Cartographic에 대한 설명입니다. (자세한 내용은 CesiumDocument를 참고하세요.)

기본적으로 Cartesian3(x,y,z)값을 갖게되며 기본 투영체 및 좌표계로 WGS84를 사용한다는 것을 알 수 있습니다.

 

결과 화면 보겠습니다.

 

라벨이 마우스를 따라다니며 위,경도를 알려주는 것을 볼 수 있습니다. 제주 한라산의 위,경도는 사진과 같군요 

이번 시간에는 Cesium JS에서 gltf 포맷을 이용한 가상의 시나리오를 만들어 보겠습니다.

시나리오는 마포대교 위에 비행하는 드론이 실시간으로 교통상황을 알리는 내용입니다.

 

HeadingPitchRange 설명 (CesiumDocument)

HeadingPitchRange는 시각 및 관점에 대한 값을 정의하는것입니다.

Heading은 방향을 나타냅니다. 360'와 0' 그리고 프레임 중심을 기준으로 양의 값일때에는 동쪽, 음의 값일때에는 서쪽으로 각이 변경됩니다.

 

Pitch는 각을 나타냅니다. 여기서의 각은 평면(x,y)을 기준으로 양의 값일때에는 올라가고 음의 값일때에는 내려가게됩니다.

 

 

Range는 거리를 나타냅니다. 프레임 중심으로부터의 거리를 조절할 수 있습니다. 

 

상기 내용은 필자가 기본값(0.0)을 토대로 heading, pitch, roll 각각 임의의 값을 넣어서 테스트 한 것임을 알려드립니다.  

 

결과부터 보시겠습니다.

서비스바로가기

 

* 이번 게시물에서 필자가 중요하다고 생각하는 소스코드입니다. 

 
/*************
    heading: Heading변경 슬라이드 값 - 0~360까지의 값 
    pitch: Pitch변경 슬라이드 값- 0~150까지의 값
    range: Range변경 슬라이드 값 - 0~60까지의 값
    **************/    
    var staticPosition = Cesium.Cartesian3.fromDegrees(126.93320937.515165,2200);
    var orientation = new Cesium.HeadingPitchRange(heading, pitch, range);
    viewer.scene.camera.setView({
        // staticPosition -- (126.933209, 37.515165, 2200) <- 마포대교를 바라보기 위한 위치(좌표) 
        destination : staticPosition,    
        // orientation -- heading, pitch, range 값 
        orientation : orientation                
    });
cs

staticPosition이라는 변수에 마포대교를 바라보는 관점 즉, 위치를 지정합니다.

유저 컨트롤을 통해 획득한 값을 활용하여 관점을 변경할 수 있습니다.

 

* 결과화면을 보겠습니다. 마포대교 모델 상공에 드론 모델이 비행하는 모습을 볼 수 있습니다.

 

 

마포대교를 클릭 했을 시 차량 수와 교통 수준 정도가 조건을 토대로 랜덤하게 표출되는것을 볼 수 있습니다.

 

유저 컨트롤을 통해 heading, pitch, range 값을 조절할 수 있습니다. 슬라이드를 통해 각 값을 조절하고 변경 버튼을 통해 관점을 변경할 수 있습니다.

 

heading에 임의의 값을 주었더니 관점이 변경된 것을 볼 수 있습니다. 독자 여러분도 슬라이드와 버튼을 통해 관점을 변경하여 보세요.

Tip. 관점의 변경은 구체(원)를 생각하시면 이해하기 쉽습니다. 

이번 시간에는 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. 항공기를 바라 본 모습입니다.

 

Cesium JS에서 시점 변경 기능 활용하기

이번엔 Cesium JS를 활용하여 시점 변경 기능을 만들어 보도록하겠습니다.

서비스바로가기


1. 카메라 시점 변경 기능을 위한 "range" Element 구성     


<!DOCTYPE html>
<html lang="en">
<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">
</head>
<body>
<div id="cesiumContainer" style="width:auto; height:600px;"></div>
 
<div>
    <h2>카메라 시점 변경하기</h2>
    <input type="range" id="controllbar" name="range_value" min="500" max="15000" step="100" onchange="lookAtTransform(value)">
</div>
 
</body>
</html>
cs

- 최소값을 500 , 최대값을 15000으로 설정하고 step을 100으로 잡아 한번의 이동 시 100만큼의 값이 조절되도록 하였습니다.

- onchange함수를 설정하여줍니다.


실행화면은 다음과 같습니다.


2. script 태그 안에 아래와 같은 소스코드를 적용합니다.


<script type="text/javascript">
    var extent = Cesium.Rectangle.fromDegrees(117.89628431.499028139.59738043.311528);
  
    Cesium.Camera.DEFAULT_VIEW_RECTANGLE = extent;
    Cesium.Camera.DEFAULT_VIEW_FACTOR = 0.7;
 
    Cesium.Ion.defaultAccessToken = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJqdGkiOiJkOGMxZjMzNy01N2FkLTQ3YTctODU0NS05NGY0MmE3MGJiOWEiLCJpZCI6NjExNywic2NvcGVzIjpbImFzciIsImdjIl0sImlhdCI6MTU0NTI3OTE3NH0.6VdcqK6vL7faWx_vYkkOuNNa8dapTn1geCi7qYBhGCw';
    var viewer = new Cesium.Viewer('cesiumContainer',
        {
            timeline : false,
            animation : false,
            selectionIndicator : false,
            navigationHelpButton : false,
            infoBox : false,
            navigationInstructionsInitiallyVisible : false   
        });
    
    //카메라 시점 조절하기 
    function lookAtTransform(value){
        var transform = Cesium.Transforms.eastNorthUpToFixedFrame(Cesium.Cartesian3.fromDegrees(126.92342837.524969)); // 카메라 시점이 적용될 위,경도         
        var camera = viewer.camera; //camera 선언
        
        camera.constrainedAxis = Cesium.Cartesian3.UNIT_Z;
        camera.lookAtTransform(transform, new Cesium.Cartesian3(-10000.0-10000.0, value)); // 시점 변경을 위한 초기범위 설정    
    }
</script>
cs

"value"는 input태그 안 controllbar의 움직임에 따라 고도(각도)값이 변경됩니다. 


전체 소스코드는 아래와 같습니다.

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
<!DOCTYPE html>
<html lang="en">
<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">
</head>
<body>
<div id="cesiumContainer" style="width:auto; height:600px;"></div>
 
<div>
    <h2>카메라 시점 변경하기</h2>
    <input type="range" id="controllbar" name="range_value" min="500" max="15000" step="100" onchange="lookAtTransform(value)">
</div>
 
<script type="text/javascript">
    var extent = Cesium.Rectangle.fromDegrees(117.89628431.499028139.59738043.311528);
  
    Cesium.Camera.DEFAULT_VIEW_RECTANGLE = extent;
    Cesium.Camera.DEFAULT_VIEW_FACTOR = 0.7;
 
    Cesium.Ion.defaultAccessToken = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJqdGkiOiJkOGMxZjMzNy01N2FkLTQ3YTctODU0NS05NGY0MmE3MGJiOWEiLCJpZCI6NjExNywic2NvcGVzIjpbImFzciIsImdjIl0sImlhdCI6MTU0NTI3OTE3NH0.6VdcqK6vL7faWx_vYkkOuNNa8dapTn1geCi7qYBhGCw';
    var viewer = new Cesium.Viewer('cesiumContainer',
        {
            timeline : false,
            animation : false,
            selectionIndicator : false,
            navigationHelpButton : false,
            infoBox : false,
            navigationInstructionsInitiallyVisible : false   
        });
    
    //카메라 시점 조절하기 
    function lookAtTransform(value){
        var transform = Cesium.Transforms.eastNorthUpToFixedFrame(Cesium.Cartesian3.fromDegrees(126.92342837.524969));          
        var camera = viewer.camera;
        
        camera.constrainedAxis = Cesium.Cartesian3.UNIT_Z;
        camera.lookAtTransform(transform, new Cesium.Cartesian3(-10000.0-10000.0, value));        
    }
</script>
</body>
</html>        
cs


완성된 최저, 중간, 최상으로 움직였을때의 화면입니다.

 - 자세한 기능을 보기위해 실행 화면 우 상단 baseLayer Map을 "Terrain Map"으로 변경합니다.

사진과 같이 controllbar 조절에 따라 시점이 변경되는 것을 볼 수 있습니다.

서비스바로가기

+ Recent posts