2019년 6월 3일 월요일

Cesium에서 피사체를 바라 보도록 카메라 위치와 방향 지정하기

flyTo(), setView()를 사용하여 카메라 뷰 지정


/**********************************************************
 * 주어진 좌표와 고도에 카메라를 고정하고 하향식 보기로 뷰 설정
 **********************************************************/
//flyTo를 사용한 하향식 보기
viewer.camera.flyTo({
    destination : Cesium.Cartesian3.fromDegrees(-117.16, 32.71, 15000.0)
});
//setView를 사용한 하향식 보기
viewer.camera.setView({
    destination : Cesium.Cartesian3.fromDegrees(126, 33, 15000.0)
});

/**********************************************************
 * 주어진 지도위의 사각형 범위를 바라 보도록 카메라를 하향식 보기로 뷰 설정
 **********************************************************/
//flyTo를 사용한 하향식 보기
viewer.camera.flyTo({
    destination : Cesium.Rectangle.fromDegrees(west, south, east, north)
});
//setView를 사용한 하향식 보기
viewer.camera.setView({
    destination : Cesium.Rectangle.fromDegrees(126.519, 33.512,  126.525, 33.515)
});

/**********************************************************
 * 주어진 좌표와 heading, pitch, roll 값에 의한 보기로 뷰 설정
 **********************************************************/
//scene에서 setView 사용
scene.camera.setView({
	destination: Cesium.Cartesian3.fromDegrees(129.210, 35.260, 700),
	orientation: new Cesium.HeadingPitchRoll(
		Cesium.Math.toRadians(10),
		Cesium.Math.toRadians(-10),
		0
	)
});
//viewer에서 setView 사용
viewer.camera.setView({
	destination: Cesium.Cartesian3.fromDegrees(129.210, 35.260, 700),
    orientation: {
		heading: Cesium.Math.toRadians(10),
		pitch: Cesium.Math.toRadians(-10),
		roll: 0
    }
});

/**********************************************************
 * 주어진 카메라 위치와 단위 벡터(방향) 값을 사용하여 카메라 뷰 설정
 **********************************************************/
//flyTo를 사용한 카메라 뷰
viewer.camera.flyTo({
    destination : Cesium.Cartesian3.fromDegrees(-122.19, 46.25, 5000.0),
    orientation : {
        direction : new Cesium.Cartesian3(-0.04231243104240401, -0.20123236049443421, -0.97862924300734),
        up : new Cesium.Cartesian3(-0.47934589305293746, -0.8553216253114552, 0.1966022179118339)
    }
});

//setView를 사용한 카메라 뷰
viewer.camera.setView({
    destination : Cesium.Cartesian3.fromDegrees(126.52, 33.51, 5000.0), //목적지 좌표 설정
    orientation : { //앵글을 정의하는 객체
        direction : new Cesium.Cartesian3(-0.04231243104240401, -0.20123236049443421, -0.97862924300734),
        up : new Cesium.Cartesian3(-0.47934589305293746, -0.8553216253114552, 0.1966022179118339)
    }
});

//flyTo에서 단위 백터를 사용한 또 다른 실사용 예
var cameraInfos = '{"position":{"x":-3168183.315714279,"y":4277980.989185754,"z":3501601.690899901},
 "direction":{"x":0.9478693177748262,"y":-0.2921556914201535,"z":0.12723524822900956},
 "up":{"x":0.08625042053669091,"y":0.6195971755307327,"z":0.7801667802666187},
 "right":{"x":-0.3067647655424749,"y":-0.7285220600950602,"z":0.6124957033127008},
 "transform":{"0":1,"1":0,"2":0,"3":0,"4":0,"5":1,"6":0,"7":0,"8":0,"9":0,"10":1,"11":0,"12":0,"13":0,"14":0,"15":1}}';
var test = JSON.parse(cameraInfos); //카메라 방향값을 Object 변수로 받기
//카메라가 날아서 이동하여 정해준 방향 값에 맞는 위치와 앵글이 되도록 함
viewer.camera.flyTo({
    destination : Cesium.Cartesian3.fromArray([test.position.x, test.position.y, test.position.z]), //목적지 좌표 설정
    orientation : { //앵글을 정의하는 객체
        direction : test.direction,
        up : test.up,
        right : test.right,
        transform: test.transform
    },
    duration : 2, //카메라 이동 시작~종료 시간(초)
//  easingFunction : Cesium.EasingFunction.SINUSOIDAL_IN_OUT, //카메라가 움직이는 기법
    cancel : function() {
        //이전의 flyTo가 종료되기 전 flyTo가 재차 호출되면 어떻게 되나?
        //- 이전의 flyTo에 cancel이 호출됨 : cancel은 함수 시작시 발생
        //- 이전의 flyTo에 complete가 호출되지 않음 : complete는 함수 종료시 발생
    },
    complete : function() {
        if (typeof callback === 'function') {
            callback();
        }
    }
});

/**********************************************************
 * 주어진 카메라 위치와 heading, pitch, roll을 사용하여 카메라 뷰 설정
 **********************************************************/
//flyTo를 사용한 카메라 뷰
viewer.camera.flyTo({
    destination : Cesium.Cartesian3.fromDegrees(-122.19, 46.25, 5000.0),
    orientation : {
        heading : Cesium.Math.toRadians(175.0),
        pitch : Cesium.Math.toRadians(-35.0),
        roll : 0.0
    }
});
//카메라가 날아서 이동하여 정해준 위도, 경도, 고도 값에 맞는 수직하향보기 상태가 되도록 함
viewer.camera.flyTo({
    destination : Cesium.Cartesian3.fromDegrees(126.52, 33.53, 500), //목적지 좌표 설정
    orientation : { //앵글을 정의하는 객체
        heading : Cesium.Math.toRadians(0),
        pitch : Cesium.Math.toRadians(-90)
    },
    duration : 2, //카메라 이동 시작~종료 시간(초)
    easingFunction : Cesium.EasingFunction.SINUSOIDAL_IN_OUT, //카메라가 움직이는 기법
    complete : function() {
        if (typeof callback === 'function') {
            callback();
        }
    }
});

//setView를 사용한 카메라 뷰
viewer.camera.setView({
    destination : Cesium.Cartesian3.fromDegrees(126.56, 33.39, 15000.0),
    orientation: { //앵글을 정의하는 객체
        heading : Cesium.Math.toRadians(0.0), //0.0:북쪽
        pitch : Cesium.Math.toRadians(-45), //0:수평, -90:수직하향
        roll : 0.0
    }
});
//카메라 위치를 그대로 유지하면서 heading, pitch, roll을 변경
viewer.camera.setView({
    orientation: { //앵글을 정의하는 객체
        heading : Cesium.Math.toRadians(0.0), //0.0:북쪽
        pitch : Cesium.Math.toRadians(-46),    //0:수평, -90:수직하향
        roll : 0.0
    }
});

/**********************************************************
 * 지도위에 올릴 개체를 사용하여 카메라 뷰 설정
 **********************************************************/
//샌드캐슬 예제 참조함
var imageryLayer = viewer.imageryLayers.addImageryProvider(new Cesium.IonImageryProvider({ assetId: 0000 }));
viewer.flyTo(imageryLayer);

같은 위치로 두번 연속 flyTo 호출시 이미 목적지 위치에 도착된 상태에서 두번 호출하는지 여부에 따라 flyTo 내부 처리가 달라진다. 목적지로 도달된 상태가 아닐때 : 두번의 flyTo 내부가 정상 작동한다 목적지에 이미 도달한 상태일때 : 첫번째 flyTo 처리에서 cancel이 호출되고 두번째 flyTo가 정상 처리된다


그 밖의 방법으로 카메라 뷰 지정


/**********************************************************
 * 지도위에 올릴 개체를 사용하여 카메라 뷰 설정
 **********************************************************/
//CesiumMilkTruck을 카메라가 바라봄
var entity = dataSource.entities.getById('CesiumMilkTruck'); //czml로부터
viewer.trackedEntity = entity;

//지도위에 추가된 모델을 카메라가 바라봄
var entity = viewer.entities.add({
    name : url,
    position : position,
    orientation : orientation,
    model : {
        uri : url,
        minimumPixelSize : 128,
        maximumScale : 20000
    }
});
viewer.trackedEntity = entity;

/**********************************************************
 * lookAt을 사용하여 카메라 뷰 설정
 **********************************************************/
//이건 직접 테스트 해보지 못함
var offset = new Cesium.HeadingPitchRange(
    Cesium.Math.toRadians(-15.0), //heading
    Cesium.Math.toRadians(-40.0), //pitch
    1500.0 //range
);
var target = Cesium.Cartesian3.fromDegrees(127.33, 36.34);
viewer.camera.lookAt(target, offset); //타겟과 오프셋을 사용하여 카메라 위치와 방향을 설정
viewer.camera.lookAtTransform(Cesium.Matrix4.IDENTITY); //lookAt에 의해 타겟 방향으로 고정된 카메라 시선을 해제

/**********************************************************
 * zoomTo를 사용하여 카메라 뷰 설정
 **********************************************************/
//이건 직접 테스트 해보지 못함
viewer.zoomTo(entity); //heading/pitch/range

//이건 직접 테스트 해보지 못함
//heading/pitch/range
var hpr = new Cesium.HeadingPitchRange(Cesium.Math.toRadians(0), Cesium.Math.toRadians(-90), 10);
viewer.zoomTo(entity, hpr);