gdalinfo

레스터 데이터 셋에 대한 정보들을 보여준다.
 

문법

 
gdalinfo [--help-general] [-mm] [-stats] [-hist] [-nogcp] [-nomd]
         [-noct] [-checksum] [-mdd domain]* datasetname

설명

gdalinfo 유틸리티 프로그램은 GDAL이 지원하는 레스터 데이터 셋에 대한 다양한 종류의 정보들을 보여준다.
-mm
데이터 셋에 각각의 band 값에 있는 실제 최소/최대 값에 대한 계산을 하여 보여주게 한다.
-stats
이미지에 대한 통계 값들을 읽고 보여준다. 이미지에 통계 값들이 있지 않으면 계산과정으로 넘어가계한다.
-hist
모든 band에 대한 히스토그램을 보고하게 한다.
-nogcp
GCP(ground control point) 리스트를 프린트하지 않게 한다. 만약 수 천 개의 GCP를 가지고 있는 L1B AVHRR 혹은 HDF4 MODIS와 같이 데이터 셋이 많은 양의 GCP들을 가지고 있다면 유용할 것이다.
-nomd
메타데이터를 프린트하지 않게 한다. 몇몇 데이터 셋은 많은 양의 메타데이터 문자열을 가지고 있다.
-noct
컬러 테이블이 프린팅 되지 않게 한다.
-checksum
데이터 셋의 각각의 밴드에 대한 checksum을 계산하게 해준다.
-mdd domain
지정된 도메인에 대한 메타데이터를 프린팅하게 해준다.

만약 있는 값이라면 gdalinfo는 다음과 같은 것들을 보고할 것이다.:

  • 파일에 접근하기 위해 사용된 포맷 드라이버
  • 레스터의 사이즈(픽셀들과 라인들).
  • 파일의 coordinate system (OGC WKT형식).
  • The geotransform associated with the file (rotational coefficients are currently not reported).
  • 지오레퍼런스된 코너들의 좌표와 geotransform에 의한 위경도 좌표(GCP들이 아님).
  • Ground control points.
  • File wide (including subdatasets) metadata.
  • Band의 데이터 타입들
  • Band color interpretation
  • Band 블럭 사이즈.
  • Band 설명.
  • Band 최소/최대 값(내부적으로 알 수 있고 계산 가능한 값)
  • Band checksum (만약에 옵션에 주어졌다면 계산됨).
  • Band NODATA 값.
  • Band overview resolutions available.
  • Band unit type (예를 들어 고도 값 밴드를 위한 "meters" 나 "feet").
  • Band pseudo-color table

예제

 
gdalinfo ~/openev/utm.tif 
Driver: GTiff/GeoTIFF
Size is 512, 512
Coordinate System is:
PROJCS["NAD27 / UTM zone 11N",
    GEOGCS["NAD27",
        DATUM["North_American_Datum_1927",
            SPHEROID["Clarke 1866",6378206.4,294.978698213901]],
        PRIMEM["Greenwich",0],
        UNIT["degree",0.0174532925199433]],
    PROJECTION["Transverse_Mercator"],
    PARAMETER["latitude_of_origin",0],
    PARAMETER["central_meridian",-117],
    PARAMETER["scale_factor",0.9996],
    PARAMETER["false_easting",500000],
    PARAMETER["false_northing",0],
    UNIT["metre",1]]
Origin = (440720.000000,3751320.000000)
Pixel Size = (60.000000,-60.000000)
Corner Coordinates:
Upper Left  (  440720.000, 3751320.000) (117d38'28.21"W, 33d54'8.47"N)
Lower Left  (  440720.000, 3720600.000) (117d38'20.79"W, 33d37'31.04"N)
Upper Right (  471440.000, 3751320.000) (117d18'32.07"W, 33d54'13.08"N)
Lower Right (  471440.000, 3720600.000) (117d18'28.50"W, 33d37'35.61"N)
Center      (  456080.000, 3735960.000) (117d28'27.39"W, 33d45'52.46"N)
Band 1 Block=512x16 Type=Byte, ColorInterp=Gray

Posted by 강부자아들
,

GRASS project는 어떻게 구성되는가

GRASS 데이터는 3단계 구조로 저장된다. database, location 그리고 mapset이다. 이것들은 사용자의 컴퓨터에서 서로를 포함하는 일련의 디렉터리 형식을 가진다. 이 세가지 모두 반드시 있어야 하면 GRASS 시작시 설정되어야 한다.

Database

모든 GIS 데이터들이 저장되어 있는 데이터베이스

e.g. ~/grassdata/

Location

location 은 영역을 이루고 있는 GRASS 프로젝트이고, 투영법(투영법이 없을 수도 있음)과 같은 투영법으로 mapset을 그룹핑하고 있다. location은 GRASS database.의 하위 디렉터리에 존재한다.

e.g. world_lat_lon, utm_zone_59, or west_coast

location 은 하나 혹은 여러 개의 mapsets을 포함한다.

The Mapset

mapset 지도를 포함한다. location의 하위 디렉터리에 있으면 개념적으로 location에 여러 개의 mapset들이 있으면 그것들은 다른 사용자들을 위해 할당 되었을 수도 있다(각각의 사용자는 하나 혹은 여러개의 mapset을 소유하여 다른 사용자들이 그들의 mapset을 수정하지 못하게 한다.). 또한 project (location)를 여러 개의 하위 영역이나 하위 프로젝트로 나누기 위해 구성될 수도 있다. 구성시 특별한 제한 조건은 없다.

location에는 항상 PERMANENT라는 mapset이 존재하는데 모든 다른 mapset에서 같은 위치에 대해 데이터를 읽을 때 사용될 수 있다. 다른 mapset에서 map을 읽기 위한 읽기권한은 'g.mapsets' 커맨드를 통해서나 "@" 심볼을 mapset 이름에 붙임(e.g.map@othermapset)으로써 관리된다.

Posted by 강부자아들
,

Cross Document Messageing

Cross Document Messaging은 iframe, 탭, 윈도우 간의 안전한 cross-origin 통신을 가능하게 해준다. 또한 postMessage API를 메세지를 주고받기 위한 표준화된 방법으로서 제공하고 있다. 아래 예제에서 보여줄 것과 같이 postMessage API를 통해서 메세지를 주고 받는 것은 매우 쉽다.

    chatFrame.contentWindow.postMessage("Hello, world", "http://www.example.com");

메세지를 수신하기 위해서는 페이지에 이벤트 핸들러만 추가시켜 주면 된다. 이벤트 핸들러를 통해 메세지가 도착했을 때, origin을 확인할 수 있고 메세지로 무엇을 할지 말지 결정할 수 있다. 아래는 임으로 정의한 messageHandler라는 함수를 이용하여 메세지를 처리하는 과정을 나타내고 있다.

      window.addEventListener("message",messageHandler,true);
      function messageHandler(e) {
        switch(e.origin) {
          case "friend.example.com":
          // 메세지 처리
          processMessage(e.data);
          break;
        default:
          // 메세지의 origin을 인식할 수 없습니다.
          // 메세지 무시
        }
      }

메세지 이벤트는 dataorigin속성을 가지고 있는 DOM 이벤트이다. data속성은 메세지를 주는 곳이 보내준 실제 메세지이고 origin은 메세지를 보낸 곳이다.origin속성을 사용하여 신뢰할 수 없는 사이트에서 오는 메세지를 차단할 수 있다. 즉, 신뢰할 수 있는 목록의 사이트들만 쉽게 확인할 수 있는 것이다.

아래 그림에서 보는 것과 같이 http://chat.example.net에서 호스팅 되는 채팅위젯 iframe과 http://portal.example.com에서 호스팅되고 있는 채팅위젯 iframe을 포함하고 있는 부모 HTML 페이지가 postMessage API를 통해 통신하는 것을 볼 수 있다. (두 사이트는 .net과.com으로 다른 origin이다.)

그림1

위 예에서 채팅위젯은 iframe에 들어가 있다. 따라서 채팅위젯은 부모 페이지에는 직접적인 접근을 갖지는 못한다. 채팅위젯이 메세지를 받았을 때, 사용자에게 새로운 메세지를 받았다는 것을 메인 페이지에 알리기 위해서 postMessage를 사용할 수 있다. 이와 비슷하게, 메인 페이지(iframe을 보함하는 부모페이지:portal.example.com)도 역시 사용자의 상태정보를 데이터를 채팅위젯 페이지에 보낼 수 있다. 메인 페이지와 위젯 iframe페이지 모두 서로를 신뢰할 수 있는 origin으로 설정하므로써 서로의 메세지를 전달 받을 수 있다.

postMessage가 소개되기 전에, iframe들 간의 통신은 때때로 direct scripting을 통해서 이루어 질 수 있었다. 한 페이지에서 동작하는 스크립트가 다른 문서의 정보를 가져오는 것이다. 이것은 아마도 보안 제약으로 인해 허용되지 않았다. 이러한 직접적인 프로그램적인 접근 대신에, postMessage는 자바스크립트 컨텍스트끼리 메세지를 비동기적으로 주고 받는 방법을 제공한다. postMessage없이 크로스 도메인 통신을 하면, 브라우저가 cross-site 스크립팅 공격을 막기 위해 보안에러를 발생시킨다.

postMessage는 같은 origin을 가진 문서간에 통신을 위해서 사용될 수도 있지만, 브라우저의 same-domain policy에 의해 허용될지 않은 경우의 통신 방법으로 특히 유용하다. 하지만 postMessage가 일관성과 사용하기 쉬운 API이기 때문에 같은 origin을 가지고 있는 경우에도 사용한다. postMessage API는 HTML5 Web Workers와 같이 자바스크립트 컨텍스트 내의 통신이 필요할 때마다 사용한다.

Origin 보안에 대한 이해

HTML5는 origin이라는 개념을 도입하므로써 도메인 보안을 명확히하고 개선하였다. origin은 웹에서 신뢰할 수 있는 연결을 모델링 하기 위해 사용되는 address의 부분집합이다. origin은 scheme, host, port로 구성된다. 예를 들어 https://www.example.comhttp://www.example.com과 다른 origin이다. 왜냐하면 httpshttp라는 다른 scheme을 가지고 있기 때문이다. origin에서 path(경로)는 고려하지 않는다. 따라서 http://www.example.com/index.htmlhttp://www.example.com/page2.html은 path만 다르기 때문에 같은 origin을 갖는 것이다.

HTML5는 origin의 직렬화에 대해 정의하였다. 문자열 형식으로 API와 프로토콜에서 origin을 참조할 수 있다. 이것은 XMLHttpRequest를 이용한 cross-origin HTTP 요청과 WebSocket에서 매우 필수적이다.

Cross-origin 통신은 송신자를 origin으로 확인한다. 이것은 수신자가 신뢰할 수 없는 origin으로부터 오는 메세지나 예상되지 않은 곳에서 오는 메세지를 무시할 수 있게 한다. 더불어 어플리케이션은 이벤트 리스너를 추가하여 선택적으로 메세지를 받아야 한다. 이러한 이유들로 수상한 어플리케이션으로부터 메세지의 간섭 위험이 사라진다.

postMessage를 위한 보안지침은 메세지는 반드시 예상되지 않거나 원치 않는 origin 페이지에 전달되지 말아야 한다는 것이다. 만약 송신자가 postMessage를 호출하는 창이 특정 origin을 가지고 있지 않으면(예를 들어, 사용자가 다른 사이트를 탐색하는 경우) 브라우저는 메세지를 전달하지 않을 것이다.

이와 유사하게 메세지를 받을 때도 송신자의 origin은 메세지에 포함되어 전달된다. 메세지의 origin은 브라우저에 의해 제공되기 때문에 속일 수 없다. 이것은 수신하는 쪽에서 어떤 메세지를 처리하고 어떤 메세지를 무시할지 결정할 수 있게 해준다. 당신은 화이트리스트를 관리하여 신뢰할 수 있는 origin의 문서들의 메세지들만 처리할 수 있다.

postMessage API 사용하기

브라우저 호환성 테스트

postMessage를 호출하기 전에 브라우저의 지원여부를 확인하는 것은 좋은 생각이다. 아래의 예제는 postMessage를 브라우저의 지원하는지 확인하는 방법 중에 하나를 보여주고 있다.

    if(typeof window.postMessage === "undefined") {
        // 브라우저에서 postMessage를 지원하지 않습니다.
    }

메세지 보내기

메세지를 전달하기 위하여, 아래의 예제와 같이 타겟이 되는 window 객체에 postMessage를 호출한다.

    window.postMessage("Hello, world", "portal.example.com");

첫 번째 인자 값은 보내질 값을 나타낸다. 두 번째 인자 값은 목표로 하는 타겟의 origin이다. 메세지를 iframe에 보내기 위해서, postMessage의 contentWindow에 아래 예제와 같이 호출한다.

    document.getElementsByTagName("iframe")[0].contentWindow.postMessage("Hello, world", "chat.example.net");

메세지 이벤트 전달 받기

window 객체의 이벤트 리스너를 통해 스크립트는 아래의 코드와 같이 메세지를 전달 받을 수 있다. 이벤트 리스너 함수에서 메세지를 전달받는 어플리케이션은 메세지은 허용할지 무시할지 결정할 수 있다.

    function checkWhiteList(origin) {
        for(var i=0; i<originWhiteList.length; i++) {
            if(origin === originWhiteList[i]) {
                return true;
            }
        }
        return false;
    }
    
    function messageHandler(e) {
        if(checkWhiteList(e.origin)) {
            processMessage(e.data);
        } else {
            // 알 수 없는 origin으로부터 온 메세지는 무시한다.
        }
    }
    
    window.addEventListener("message", messageHandler, true);

postMessage API를 사용한 어플리케이션 구현

앞서 말한 포탈 어플리케이션에 cross-origin 채팅 위젯을 만든다고 한다고 가정하자. 아래 그림과 같이 Cross Document Messaging을 활용하여 채팅 위젯을 만들 수 있다

2

이 예제를 통해 우리는 포탈 페이지가 서드파티의 위젯을 iframe에 어떻게 넣는지 알았다. 우리의 예제는 http://chat.example.net의 채팅 위젯 하나였다. 포탈 페이지와 위젯은 postMessage를 통하여 통신할 수 있었다. 예제에서 채팅 위젯 iframe은 사용자에게 알림을 전달하기위해 웹 페에지에 타이틀을 깜박 거렸다. 이것은 백그라운에서 이벤트를 받는 어플리케이션들에서 찾아볼 수 있는 일반적인 UI 기술이다. 채팅위젯이 부모 페이지와는 다른 origin에서 서비스되는 iframe에 고립되어 있기 때문에, 부모 페이지의 제목을 바꾸는 것은 보안 위반이다. 대신에 채팅 위젯은 postMessage를 이용하여 부모 페이지에게 알림 메세지를 전달했다.

예제 에서 포탈 페이지는 사용자가 자신의 상태(status)를 바꾸었다고 iframe에게 메세지를 전달한다. postMessage를 이러한 방식으로 사용하므로써 이와 같은 포탈은 채팅위젯과 같이 결합된 페이지 어플리케이션에게 메세지를 전달한다. 물론 목표로 하는 origin은 화이트 리스트를 체크하여 메세지를 선택적으로 받는다. 따라서 메세지가 유출이 사고나 고의적인 의도에 의해 이루어질 수 없다.

자세한 설명을 위해 postMessagePotal.html과 postMessageWidget.html을 생성했다.

포털 페이지 만들기

첫 번째로 다른 origin에서 호스팅 되는 채팅 위젯 iframe을 포탈 페이지에 추가한다.

<iframe id="widget" src="http://chat.example.net:9999/postMessageWidget.html"></iframe>

그 다음은 messageHandler라는 이벤트 리스너를 추가하여 채팅 위젯으로부터 오는 메세지 이벤트를 가져오는 것이다. 아래에서 보는 예제 코드와 같이, 위젯은 포털에게 제목표시를 깜박거리게 할 사용자 알림을 할지를 확인하게 된다. 채팅 위젯으로부터 메세지가 오는지 확인하기 위해 메세지의 origin을 확인한다. 만약 메세지가 http://chat.example.net:9999에서 오지 않는다면 포탈페이지는 메세지를 무시할 것이다.

    var targetOrigin = "http://chat.example.net:9999";
    
    function messageHandler(e) {
        if(e.origin == targetOrigin){
            notify(e.data);
        } else {
            // 다른 도메인에서 온 메세지는 무시한다.
        }
    }

그 다음은 채팅 위젯과 통신할 수 있는 함수를 만드는 것이다. 포털 페이지에 속해 있는 위젯 iframe에게 상태 업데이트를 보내기 위해 postMessage를 사용한다. 실제 라이브 채팅 어플리케이션에서 이것은 사용자 상태(온라인, 부재중 등등)를 알리기 위해 사용될 수 있다.

    function sendString(s) {
        document.getElementById("widget").contentWindow.postMessage(s, targetOrigin);
    }

채팅위젯 페이지 만들기

첫 번째로 포털 페이지로부터 오는 메세지를 전달받기 위해 messageHandler라는 이벤트 리스너를 추가한다. 아래 예제코드와 같이 채팅 위젯은 상태 변화 메세지를 전달받게 된다. 메세지가 포탈페이지로부터 오는지 확인하기 위해 origin을 확인할 것이다. 만약 메세지가 http://portal.example.com:9999로부터 오지 않는다면 위젯페이지는 이 메세지를 무시할 것이다.

    var targetOrigin = "http://portal.example.com:9999";
    
    function messageHandler(e) {
        if(e.origin === "http://portal.example.com:9999") {
            document.getElementById("status").textContent = e.data;
        } else {
            // 다른 origin으로 부터 온 메세지는 무시한다.
        }
    }

그 다음으로 포탈페이지와 통신할 함수를 추가한다. 위젯은 포탈에게 새로운 채팅 메세지가 받아지면 postMessage를 통하여 사용자에게 알림을 할지 아래 예제와 같이 묻는다.

    function sendString(s) {
        window.top.postMessage(s, targetOrigin);
    }

최종 코드

postMessagePortal.html

<!DOCTYPE html>
<html>
    <head>
        <title>Portal [http://portal.example.com:9999]</title>
        <meta charset="UTF-8">
        <link rel="stylesheet" href="styles.css">
        <style>
            iframe {
                height: 400px;
                width: 800px;
            }
        </style>
        <link rel="icon" href="http://apress.com/favicon.ico">
        <script>
            var defaultTitle = "Portal [http://portal.example.com:9999]";
            var notificationTimer = null;
            
            var targetOrigin = "http://chat.example.net:9999";
            
            function messageHandler(e) {
                if(e.origin == targetOrigin){
                    notify(e.data);
                } else {
                    // 다른 도메인에서 온 메세지는 무시한다.
                }
            }
            
            function sendString(s) {
                document.getElementById("widget").contentWindow.postMessage(s, targetOrigin);
            }
            
            function notify(message) {
                stopBlinking();
                blinkTitle(message, defaultTitle);
            }
            
            function stopBlinking() {
                if(notificationTimer !== null){
                    clearTimeout(notificationTimer);
                }
                document.title = defaultTitle;
            }
            
            function blinkTitle(m1, m2){
                  document.title = m1;
                // setTimeout함수의 3번 째 인수부터는 콜백함수의 인자 값으로 들어간다.
                // 여기서는 blickTitle 함수의 인자 값으로 m2, m1을 사용하는 것이다.
                notificationTimer = setTimeout(blinkTitle, 1000, m2, m1);
            }
            
            function sendStatus() {
                var statusText = document.getElementById("statusText").value;
                sendString(statusText);
            }
            
            function loadDemo() {
                document.getElementById("sendButton").addEventListener("click", sendStatus,true);    
                document.getElementById("stopButton").addEventListener("click", stopBlinking,true);
                sendStatus();    
            }
            window.addEventListener("load", loadDemo, true);
            window.addEventListener("message", messageHandler, true);
            
        </script>
    </head>
    <body>
        <h1>Cross-Origin 포탈</h1>
        <p><b>Origin</b>: http://portal.example.com:9999</p>
        Status <input type="text" id="statusText" value="Online">
        <button id="sendButton">Change Status</button>
        <p>이것은 포텔 페이지에 포함되어 있는 위젯 iframe에 상태를 업데이트 하기 위해 postMessage를 이용한다.</p>
        <iframe id="widget" src="http://chat.example.net:9999/postMessageWidget.html"></iframe>
        <p>
            <button id="stopButton">페이지의 타이틀이 깜박거리는 것을 중지</button>
        </p>                
    </body>
</html>

postMessageWidget.html

<!DOCTYPE html>
<html>
    <head>
        <title>Chat Widget</title>
        <meta charset="UTF-8">
        <link rel="stylesheet" href="styles.css">
        <script>
            var targetOrigin = "http://portal.example.com:9999";
            
            function messageHandler(e) {
                if(e.origin === "http://portal.example.com:9999") {
                    document.getElementById("status").textContent = e.data;
                } else {
                    // 다른 origin으로 부터 온 메세지는 무시한다.
                }
            }
            
            function sendString(s) {
                window.top.postMessage(s, targetOrigin);
            }
            
            function loadDemo() {
                document.getElementById("actionButton").addEventListener("click",
                    function () {
                        var messageText = document.getElementById("messageText").value;
                        alert("test");
                        sendString(messageText);
                    }, true);
            }
            
            window.addEventListener("load", loadDemo, true);
            window.addEventListener("message", messageHandler, true);
        </script>
    </head>
    <body>
        <h1>위젯 iframe</h1>
        <p><b>Origin</b>: http://chat.example.net:9999</p>
        <p>포탈에 포함되어 있는 Status를 다음과 같이 설정: <strong id="status"></strong></p>
        <div>
            <input type="text" id="messageText" value="Widget notification.">
            <button id="actionButton">Notification 보내기</button>
        </div>
        <p>이것은 포탈 사이트가 사용자에게 알리지 물을 것이다. 포털 사이트의 제목표시줄은 제목을 깜박거리며 번갈아 가며 반복적으로 보여줄 것이다. 만약 메세지가  http://chat.example.net:9999 이외에서 온다면 포탈 페이지는 이 메세지들을 무시할 것이다.</p>
    </body>
</html>

동작하는 어플리케이션 만들기(서버 세팅)

    1. C:\WINDOWS\system32\drivers\etc 경로로 가서 “hosts” 파일을 메모장으로 엽니다
image
    2. 아래 그림과 같이 127.0.0.1과 chat.example.net, portal.example.com을 적어 넣고 저장합니다image
        3. http://python.org/download/를 방문하여 Python 2.7.1 Python2.7.1 Windows installer를 다운로드 합니다.image
        4. 파이썬이 설치 된 폴더에 책을 보고, 작성하신 postMessagePortal.html과 postMessageWidget.html 파일을 넣습니다
      image
        5. “시작”>”실행”>cmd를 입력하여 커맨드 창을 실행시킨 후 cd C:\Python27을 입력합니다.
      image
        6. 커맨드 창에 python –m SimpleHTTPServer 9999를 입력합니다.

      image

        7. 위의 설정을 다 한후, postMessage API를 지원하는 브라우저의 주소창에 http://portal.example.com:9999/postMessagePortal.html을 입력합니다.
      Posted by 강부자아들
      ,