📋
XDWorld_WebGL_Manual
  • 소개
    • XDWorld API
    • 시작하기
    • About EGIS
    • Release Note
      • 2.1x 버전 업데이트
      • 2.x 버전 업데이트
      • 1.6x 버전 업데이트
      • 1.5x 버전 업데이트
      • 1.4x 버전 업데이트
      • 1.3x 버전 업데이트
      • 이전 버전 업데이트
    • Tutorial
      • 카메라 설정
      • POI 생성하기
      • 폴리곤 생성하기
      • 라인 생성하기
      • 모델 추가하기
      • 레이어 설정
      • 배경 지도 설정
      • 거리 측정
      • 면적 측정
      • 높이 측정
      • 반경 측정
  • API
    • Module
    • Core
      • Collection
      • JSAABBox3D
      • JSColor
      • JSLine3D
      • JSSize2D
      • JSSize3D
      • JSVector2D
      • JSVector3D
      • JSVec2Array
      • JSVec3Array
      • JSDateTime
    • Analysis
      • JSAnalysis
      • JSAnalysisGridShadow
      • JSEarthquake
      • JSEditTerrain
      • JSFlood
      • JSGridAnal
      • JSSightAnalysis
      • JSSlope
      • JSTransparency
      • JSSolarManager
    • Camera
      • JSCamera
    • Layer
      • JSLayer
      • JSLayerList
      • JSImageryProvider
    • Map
      • JSMap
      • JSTerrain
      • JSIndexMap
    • Object
      • JSObject
      • JSAntenna
      • JSArrow
      • JSBarGraph
      • JSBarGraph3D
      • JSBillboard
      • JSColorGrid
      • JSColorGrid3D
      • JSColorPolygon
      • JSFigure
      • JSFlow
      • JSFlowPolygon
      • JSGhostSymbol
      • JSGhostSymbolMap
      • JSHTMLObject
      • JSIcon
      • JSInstanceObject
      • JSLineString
      • JSMultiCube
      • JSMultiPoint
      • JSPipe
      • JSPoint
      • JSPointGraph
      • JSPolygon
      • JSPolygonStyle
      • JSPolyLineStyle
      • JSReal3D
      • JSSurfaceGraph
      • JSSymbol
      • JSTimeSeriesObject
      • JSTraceTarget
      • JSTyphoon
      • JSVideoObject
      • JSViewFrustum
    • Option
      • JSControl
      • JSNavigationControl
      • JSOption
    • ETC
      • JSMath
      • JSProj
      • ~~JSProjection~~
      • SOPObject
      • EVENT
      • Type List
      • Tag List
Powered by GitBook
On this page
  • Global 변수
  • 기능 구현
  • step 1. 레이어 생성
  • step 2. 이벤트 등록
  • step 3. 마우스모드 변경
  • step 4 - 1. 높이 Icon 생성
  • step 4 - 2. 높이 Point Icon 생성
  • step 4 - 3. 높이 사각형 Icon 생성
  • step 4 - 4. 높이 측정 결과 값 Icon 생성
  • step 4 - 5. 높이 측정 단위(m/km) 텍스트 변환
  • step 5. 높이 객체 생성
  • step 6. 높이 측정 초기화
  • 결과 화면

Was this helpful?

  1. 소개
  2. Tutorial

높이 측정

지도 내에서 해발고도, 상대고도를 측정하여 출력하는 과정을 소개합니다.

Previous면적 측정Next반경 측정

Last updated 3 years ago

Was this helpful?

본 페이지에서는 지도의 마우스 모드를 높이 측정 모드로 변경한 후 클릭한 지점의 측정 결과를 로 가시화 하는 과정에 대하여 알아봅니다.

해발고도와 지면고도

높이는 기준점에 따라 해발고도, 지면고도 값이 주로 쓰입니다.

  • 해발고도 : 해수면을 기준으로 측정한 높이

  • 지면고도 : 지면을 기준으로 측정한 높이

본 샘플 코드에서는 지면을 클릭한 경우 해발고도 값을, 건물이나 기타 시설물을 클릭한 해발고도 값과 지면고도 값을 함께 표시하도록 구성하였습니다.

위 기능을 구현하는 전체 코드입니다.
//* 엔진 로드 후 실행할 초기화 함수(Module.postRun) */
function init() {

    // 엔진 초기화 API 호출(필수)
    Module.Start(window.innerWidth, window.innerHeight);

    // 카메라 위치 설정
    Module.getViewCamera().setLocation(new Module.JSVector3D(126.92836647767662, 37.52439503321471, 1000.0));

    // 아이콘 관리 심볼 생성
    GLOBAL.Symbol = Module.getSymbol();

    // 분석 출력 POI 레이어 생성
    var layerList = new Module.JSLayerList(true);
    GLOBAL.Layer = layerList.createLayer("MEASURE_POI", Module.ELT_3DPOINT);
    GLOBAL.Layer.setMaxDistance(20000.0);
    GLOBAL.Layer.setSelectable(false);
	
    Module.XDEMapCreateLayer("facility_build", "http://xdworld.vworld.kr:8080", 8080, true, true, false, 9, 0, 15);
	
    initEvent(Module.canvas);
}

var GLOBAL = {
    Symbol : null,		// 아이콘 관리 심볼 객체
    Layer : null,		// POI 저장 레이어
    nIndex : 0			// POI, Icon 생성 인덱스
};

/* 이벤트 설정 */
function initEvent(canvas) {

    // 거리측정 이벤트 설정
    canvas.addEventListener("Fire_EventAddAltitudePoint", function(e){
        createPOI(
            new Module.JSVector3D(e.dLon, e.dLat, e.dAlt),
	    "rgba(10, 10, 0, 0.5)",
            e.dGroundAltitude, e.dObjectAltitude
        );
    });
}

/* 마우스 상태 변경 */
function setMouseState(_option){

    // 마우스 모드 설정
    Module.XDSetMouseState(_option);
}

/* 분석 내용 출력 POI 생성 */
function createPOI(_position, _color, _value, _subValue) {

    // POI 아이콘 이미지를 그릴 Canvas 생성
    var drawCanvas = document.createElement('canvas');
    drawCanvas.width = 200;
    drawCanvas.height = 100;

    // 아이콘 이미지 데이터 반환
    var imageData = drawIcon(drawCanvas, _color, _value, _subValue),
	nIndex = GLOBAL.nIndex
        ;

    // 심볼에 아이콘 이미지 등록
    if (GLOBAL.Symbol.insertIcon("Icon"+nIndex, imageData, drawCanvas.width, drawCanvas.height)) {

        // 등록한 아이콘 객체 반환
        var icon = GLOBAL.Symbol.getIcon("Icon"+nIndex);

        // JSPoint 객체 생성
        var count = GLOBAL.Layer.getObjectCount(),
            poi = Module.createPoint("POI"+nIndex)
            ;

        poi.setPosition(_position); // 위치 설정
        poi.setIcon(icon); // 아이콘 설정

        // 레이어에 오브젝트 추가
        GLOBAL.Layer.addObject(poi, 0);

        // 인덱스 값 상승
        GLOBAL.nIndex++;
    }
}

/* 아이콘 이미지 데이터 반환 */
function drawIcon(_canvas, _color, _value, _subValue) {

    // 컨텍스트 반환 및 배경 초기화
    var ctx = _canvas.getContext('2d'),
        width = _canvas.width,
        height = _canvas.height
        ;
    ctx.clearRect(0, 0, width, height);

    // 배경과 높이 값 텍스트 그리기
    if (_subValue == -1) {
        drawRoundRect(ctx, 50, 20, 100, 20, 5, _color);		// 오브젝트 높이 값이 유효하지 않는 경우
    } else {
        drawRoundRect(ctx, 50, 5, 100, 35, 5, _color);		// 오브젝트 높이 값이 유효한 경우
        setText(ctx, width*0.5, height*0.2, '지면고도 : ' + setKilloUnit(_subValue, 0.001, 0));
    }
    setText(ctx, width*0.5, height*0.2+15, '해발고도 : '+ setKilloUnit(_value, 0.001, 0));

    // 위치 표시 점 그리기
    drawDot(ctx, width, height);

    return ctx.getImageData(0, 0, _canvas.width, _canvas.height).data;
}

/* 위치 표시 점 그리기 */
function drawDot(ctx, width, height) {

    ctx.beginPath();
    ctx.lineWidth = 6;
    ctx.arc(width*0.5, height*0.5, 2, 0, 2*Math.PI, false);
    ctx.closePath();

    ctx.fillStyle = 'rgba(255, 0, 0, 0.8)';
    ctx.fill();
    ctx.lineWidth = 8;
    ctx.strokeStyle = "rgba(255, 255, 0, 0.8)";
    ctx.stroke();
}

/* 둥근 사각형 배경 그리기 */
function drawRoundRect(ctx, x, y, width, height, radius, color) {

    if (width < 2 * radius) {
        radius = width * 0.5;
    }
    if (height < 2 * radius) {
        radius = height * 0.5;
    }

    ctx.beginPath();
    ctx.moveTo(x+radius, y);
    ctx.arcTo(x+width, y, x+width, y+height, radius);
    ctx.arcTo(x+width, 	y+height, x, y+height, radius);
    ctx.arcTo(x, y+height, x, y, radius);
    ctx.arcTo(x, y, x+width, y, radius);
    ctx.closePath();

    // 사각형 그리기
    ctx.fillStyle = color;
    ctx.fill();
    
    return ctx;
}

/* 텍스트 그리기 */
function setText(_ctx, _posX, _posY, _strText) {

    _ctx.font = "bold 12px sans-serif";
    _ctx.textAlign = "center";

    _ctx.fillStyle = "rgb(255, 255, 255)";
    _ctx.fillText(_strText, _posX, _posY);
}

/* m/km 텍스트 변환 */
function setKilloUnit(_text, _meterToKilloRate, _decimalSize){

    if (_decimalSize < 0){
    	_decimalSize = 0;
    }
    if (typeof _text == "number") {
    	if (_text < 1.0/(_meterToKilloRate*Math.pow(10,_decimalSize))) {
            _text = _text.toFixed(1).toString()+'m';
	} else {
	    _text = (_text*_meterToKilloRate).toFixed(2).toString()+'㎞';
	}
    }
    return _text;
}

/* 분석 내용 초기화 */
function clearAnalysis() {

    var layer = GLOBAL.Layer,
        symbol = GLOBAL.Symbol;
    if (layer == null) {
    	return;
    }

    // 등록된 아이콘 리스트 삭제
    var i, len, icon, poi;
    for (i=0, len=layer.getObjectCount(); i<len; i++) {

    	poi = layer.keyAtObject("POI"+i);
    	icon = poi.getIcon();

	// 아이콘을 참조 중인 POI 삭제
	layer.removeAtKey("POI"+i);

	// 아이콘을 심볼에서 삭제
	symbol.deleteIcon(icon.getId());
    }

    // POI, Icon 키 지정 인덱스 초기화
    GLOBAL.nIndex = 0;
}

이어서 코드의 세부 단계에 대해 알아봅니다.

Global 변수

기능을 구현하기 전 전역으로 사용하는 변수를 선언한 부분입니다.

var GLOBAL = {
    Symbol : null,    // 아이콘 관리 심볼 객체
    Layer : null,     // POI 저장 레이어
    nIndex : 0        // POI, Icon 생성 인덱스
};

Symbol

이미지 텍스쳐를 저장하는 텍스쳐 맵 오브젝트를 이 곳에 저장합니다.

Layer

기능 구현

step 1. 레이어 생성

높이 측정 Icon 및 높이 값을 가시화 할 레이어를 생성합니다.

var layerList = new Module.JSLayerList(true);

GLOBAL.Layer = layerList.createLayer("MEASURE_POI", Module.ELT_3DPOINT);
GLOBAL.Layer.setMaxDistance(20000.0);
GLOBAL.Layer.setSelectable(false);

step 2. 이벤트 등록

엔진 내부에서 계산된 높이를 반환 받기 위해 이벤트를 등록합니다.

function initEvent(canvas) {
    canvas.addEventListener("Fire_EventAddAltitudePoint", function(e){
        createPOI(
            new Module.JSVector3D(e.dLon, e.dLat, e.dAlt),
            "rgba(10, 10, 0, 0.5)",
            e.dGroundAltitude, e.dObjectAltitude
        );
    });
}

Fire_EventAddAltitudePoint 이벤트는 마우스 모드가 MML_ANALYS_ALTITUDE 일 경우 발생합니다.

마우스 모드를 변경한 후 지도를 클릭하면 이벤트를 통해 높이 정보가 이벤트 파라미터로 반환 됩니다.

  • dLon : 높이를 측정한 위치의 경도 값

  • dLat : 높이를 측정한 위치의 위도 값

  • dAlt : 높이를 측정한 위치의 고도 값

  • dGroundAltitude : 해발 고도 값. 지면을 클릭한 경우 dAlt 값과 동일한 값이 출력 될 것입니다.

  • dObjectAltitude : 지면고도 값

step 3. 마우스모드 변경

높이 측정을 위해서 마우스 모드를 변경합니다.

Module.XDSetMouseState(Module.MML_ANALYS_ALTITUDE);

step 4 - 1. 높이 Icon 생성

아래 함수는 반환 받은 높이 값을 랜더링하기 위해 Icon을 생성합니다.

함수를 실행하면 아래와 같이 이미지가 canvas에 생성될 것입니다.

function drawIcon(_canvas, _color, _value, _subValue) {

    // 컨텍스트 반환 및 배경 초기화
    var ctx = _canvas.getContext('2d'),
        width = _canvas.width,
        height = _canvas.height
        ;
        
    ctx.clearRect(0, 0, width, height);

    // 배경과 높이 값 텍스트 그리기
    if (_subValue == -1) {
        drawRoundRect(ctx, 50, 20, 100, 20, 5, _color); // 오브젝트 높이 값이 유효하지 않는 경우
    } else {
        drawRoundRect(ctx, 50, 5, 100, 35, 5, _color); // 오브젝트 높이 값이 유효한 경우
        setText(ctx, width*0.5, height*0.2, '지면고도 : ' + setKilloUnit(_subValue, 0.001, 0));
    }
    setText(ctx, width*0.5, height*0.2+15, '해발고도 : '+ setKilloUnit(_value, 0.001, 0));

    // 위치 표시 점 그리기
    drawDot(ctx, width, height);

    return ctx.getImageData(0, 0, _canvas.width, _canvas.height).data;
}

step 4 - 2. 높이 Point Icon 생성

높이 측정한 위치를 가시화 하기 위한 Point Icon을 생성합니다.

function drawDot(ctx, width, height) {

    ctx.beginPath();
    ctx.lineWidth = 6;
    ctx.arc(width*0.5, height*0.5, 2, 0, 2*Math.PI, false);
    ctx.closePath();

    ctx.fillStyle = 'rgba(255, 0, 0, 0.8)';
    ctx.fill();
    ctx.lineWidth = 8;
    ctx.strokeStyle = "rgba(255, 255, 0, 0.8)";
    ctx.stroke();
}

step 4 - 3. 높이 사각형 Icon 생성

반환 받은 높이 값을 가시화 할 배경으로 사각형을 그립니다.

function drawRoundRect(ctx, x, y, width, height, radius, color) {

    if (width < 2 * radius) {
        radius = width * 0.5;
    }
    
    if (height < 2 * radius) {
        radius = height * 0.5;
    }

    ctx.beginPath();
    ctx.moveTo(x+radius, y);
    ctx.arcTo(x+width, y, x+width, y+height, radius);
    ctx.arcTo(x+width, y+height, x, y+height, radius);
    ctx.arcTo(x, y+height, x, y, radius);
    ctx.arcTo(x, y, x+width, y, radius);
    ctx.closePath();

    // 사각형 그리기
    ctx.fillStyle = color;
    ctx.fill();

    return ctx;
}

step 4 - 4. 높이 측정 결과 값 Icon 생성

반환 받은 높이 값을 사각형 Icon에 텍스트로 작성합니다.

function setText(_ctx, _posX, _posY, _strText) {

    _ctx.font = "bold 12px sans-serif";
    _ctx.textAlign = "center";

    _ctx.fillStyle = "rgb(255, 255, 255)";
    _ctx.fillText(_strText, _posX, _posY);
}

step 4 - 5. 높이 측정 단위(m/km) 텍스트 변환

필요에 따라 반환 받은 높이 값을 m/km 텍스트로 변환합니다.

function setKilloUnit(_text, _meterToKilloRate, _decimalSize){

    if (_decimalSize < 0){
        _decimalSize = 0;
    }
    if (typeof _text == "number") {
        if (_text < 1.0/(_meterToKilloRate*Math.pow(10,_decimalSize))) {
            _text = _text.toFixed(1).toString()+'m';
        } else {
            _text = (_text*_meterToKilloRate).toFixed(2).toString()+'㎞';
        }
    }
    return _text;
}

step 5. 높이 객체 생성

생성한 Icon으로 객체를 만들고 레이어에 추가합니다.

function createPOI(_position, _color, _value, _subValue) {

    // POI 아이콘 이미지를 그릴 Canvas 생성
    var drawCanvas = document.createElement('canvas');
    drawCanvas.width = 200;
    drawCanvas.height = 100;

    // 아이콘 이미지 데이터 반환
    var imageData = drawIcon(drawCanvas, _color, _value, _subValue),
        nIndex = GLOBAL.nIndex
        ;

    // 심볼에 아이콘 이미지 등록
    if (GLOBAL.Symbol.insertIcon("Icon"+nIndex, imageData, drawCanvas.width, drawCanvas.height)) {

        // 등록한 아이콘 객체 반환
        var icon = GLOBAL.Symbol.getIcon("Icon"+nIndex);

        // JSPoint 객체 생성
        var count = GLOBAL.Layer.getObjectCount(),
            poi = Module.createPoint("POI"+nIndex)
	    ;

        poi.setPosition(_position);    // 위치 설정
        poi.setIcon(icon);             // 아이콘 설정

        // 레이어에 오브젝트 추가
        GLOBAL.Layer.addObject(poi, 0);

        // 인덱스 값 상승
        GLOBAL.nIndex++;
    }
}

step 6. 높이 측정 초기화

높이 측정 결과 및 객체를 초기화합니다.

function clearAnalysis() {

    var layer = GLOBAL.Layer,
        symbol = GLOBAL.Symbol;
        
    if (layer == null) {
        return;
    }

    // 등록된 아이콘 리스트 삭제
    var i, len, icon, poi;
    for (i=0, len=layer.getObjectCount(); i<len; i++) {

        poi = layer.keyAtObject("POI"+i);
        icon = poi.getIcon();

        // 아이콘을 참조 중인 POI 삭제
        layer.removeAtKey("POI"+i);

        // 아이콘을 심볼에서 삭제
        symbol.deleteIcon(icon.getId());
    }

    // POI, Icon 키 지정 인덱스 초기화
    GLOBAL.nIndex = 0;
}

결과 화면

위 과정을 모두 거치면 클릭한 지점에 높이 정보를 표시하는 측정 기능이 완성됩니다.

에 대한 간략한 설명은 거리 측정 튜토리얼의 항목의 JSSymbol 설명을 참조하세요.

생성한 오브젝트를 저장할 레이어를 이 변수에 저장합니다.

레이어를 저장하는 과정은 단계를 참조하세요.

레이어 타입에 대한 설명은 를 참조해 주십시오.

마우스 모드를 설정하는 과정은 다음 단계 변경 항목을 참조하세요.

위 이벤트 정보를 토대로 createPOI 함수에서 고도 정보를 출력하는 오브젝트를 생성합니다.

다음 과정은 오브젝트를 생성하기 전 다양한 캔버스 그리기 함수에 대한 설명입니다.

오브젝트 생성 단계를 바로 확인하시려면 로 이동하십시오.

마우스 모드에 대한 설명은 를 참조해 주십시오.

맨 처음 이미지를 그릴 canvas를 생성하고, 글자를 작성할 배경을 칠한 후()

반환 된 고도 값을 토대로 텍스트를 입력합니다. ()

마지막으로 클릭한 지점을 표시할 수 있도록 위치 표시 점을 그립니다. ()

높이 측정 과정에 대한 라이브 코드를 확인해 보고 싶으시다면? 를 클릭해 주세요

JSPoint
여기
JSPoint
JSPoint
여기
여기
step 1.레이어 생성
step 3. 마우스모드
JSPoint
여기
step 4-3. 높이 사각형 Icon 생성
step 4-4. 높이 측정 결과 값 Icon 생성
step 4-2. 높이 Point Icon 생성
JSPoint
JSSymbol
step 5. 거리 객체 생성