GeoTiff를 Write하는 것이 그리 어렵지 않음에도 불구하고, 곳곳에서 질의가 들어오는군요. 여하간..
이런저런 이유로 GeoTiff를 만드는 과정을 정리해 보았습니다.
참고하시기 바랍니다.
GeoTiff의 Write의 일반적인 과정입니다.
-------------------
void GeoTiffWrite(const char* fname) // 새로 만드려는 TIFF 이름..
{
TIFF *tif=(TIFF*)0; // TIFF*를 일단 선언하구요.
GTIF *gtif=(GTIF*)0; // GeoTiff 포인터를 선언하구요.
tif=XTIFFOpen(fname,"w"); // TIFF 파일을 일단 엽니다.
gtif = GTIFNew(tif); // GeoTiff를 사용하겠다고 선언합니다. 이 함수(GTIFNew()는 GTIFFree()와 쌍을 이뤄야합니다.
// 여기는 일반적인 TIFF Writing을 위한 루틴입니다.
// 이 루틴과 관련해서는 Tiff Library나 Tiff writing을 참고하시기 바랍니다.
TIFFSetField(tif, TIFFTAG_IMAGEWIDTH, width);
TIFFSetField(tif, TIFFTAG_IMAGELENGTH, height);
TIFFSetField(tif, TIFFTAG_COMPRESSION, compression);
TIFFSetField(tif, TIFFTAG_PHOTOMETRIC, photometric);
TIFFSetField(tif, TIFFTAG_PLANARCONFIG, planar);
TIFFSetField(tif, TIFFTAG_BITSPERSAMPLE, bits);
// GeoTiff 좌표 임베딩 루틴..
TIFFSetField(tif,TIFFTAG_GEOTIEPOINTS, 6, tiepoints); // GTIF에 TIEPoint를 지정해 줍니다. tiepoints는 tiepoints[6]입니다.
TIFFSetField(tif,TIFFTAG_GEOPIXELSCALE, 3, pixscale); // GTIF에 Pixel Size를 지정해 줍니다. pixscale는 pixscale[3]입니다.
// 필요할 경우 GeoKey를 맞춰줍니다. Dautm이니 투영법이니 하는 것들..
// 이런 Keyset은 http://www.remotesensing.org/geotiff/spec/geotiff6.html 에서 볼 수 있습니다.
// 아래는 어디까지나 샘플입니다. 자세한 GeoKey는 위의 홈페이지를 참고하세요.
GTIFKeySet(gtif, GTModelTypeGeoKey, TYPE_SHORT, 1, ModelGeographic);
GTIFKeySet(gtif, GTRasterTypeGeoKey, TYPE_SHORT, 1, RasterPixelIsArea);
GTIFKeySet(gtif, GTCitationGeoKey, TYPE_ASCII, 0, "Just An Example");
GTIFKeySet(gtif, GeographicTypeGeoKey, TYPE_SHORT, 1, KvUserDefined);
GTIFKeySet(gtif, GeogCitationGeoKey, TYPE_ASCII, 0, "Everest Ellipsoid Used.");
GTIFKeySet(gtif, GeogAngularUnitsGeoKey, TYPE_SHORT, 1, Angular_Degree);
GTIFKeySet(gtif, GeogLinearUnitsGeoKey, TYPE_SHORT, 1, Linear_Meter);
GTIFKeySet(gtif, GeogGeodeticDatumGeoKey, TYPE_SHORT, 1, KvUserDefined);
GTIFKeySet(gtif, GeogEllipsoidGeoKey, TYPE_SHORT, 1, Ellipse_Everest_1830_1967_Definition);
GTIFKeySet(gtif, GeogSemiMajorAxisGeoKey, TYPE_DOUBLE, 1, (double)6377298.556);
GTIFKeySet(gtif, GeogInvFlatteningGeoKey, TYPE_DOUBLE, 1, (double)300.8017);
TiffWriteRoutineHere(); // 실제 Data를 기록합니다. TIFFWriteScanline같은 함수를 써서..
GTIFWriteKeys(gtif); // GTIFWriteKeys를 해주지 않으면 물리적으로 직접 GTIF 파일에 기록하지 않습니다.
GTIFFree(gtif); // GTIF를 풀어주구요..
XTIFFClose(tif); // TIF를 닫습니다.
}
결론적으로 보면,
XTIFOpen() -> GTIFNew() -> TIFFSetField() -> GTIFKeySet() -> TiffWrite() -> GTIFWriteKeys() -> GTIFFree() -> XTIFFClose() 의 순서입니다. 이 순서만 맞춰서 코딩하면 됩니다.
좌표값을 넣어주는 핵심 루틴이 바로 TIFFSetField(tif,TIFFTAG_GEOTIEPOINTS, 6, tiepoints);입니다.
tiepoints는 tiepoints[6]와 같이 선언된 배열입니다. tiepoints의 6개값의 의미는 다음과 같습니다.
첫 두 값은 영상좌표를 의미합니다. 그리고 네번째와 다섯번째 값이 실제 지상좌표계가 되겠습니다. 따라서 영상의 좌상단의 좌표값이 (200000E, 500000N)인 경우 tiepoints는 다음과 같이 나올 것입니다.
tiepoints[6] = {0, 0, 0, 200000, 500000, 0} 이해가 되시는지요.
대부분의 경우 이처럼 영상좌표의 좌상단에 지상좌표를 넣어주면 대부분의 소프트웨어가 파싱하는데, 큰 문제가 없습니다.
TIFFSetField(tif,TIFFTAG_GEOPIXELSCALE, 3,pixscale); 는 1pixel당 해상도를 영상에 기록합니다. pixscale는 pixscale[3]와 같이 선언된 배열이면 됩니다. 대부분의 경우 pixscale[3] = {xresolution, yresolution, 0}으로 기록될 것입니다.
Intergraph나 NASA의 JPL은 영상해상도와 위치등록정보를 동시에 처리하는 TIFFTAG_GEOTRANSMATRIX 이라는 태그를 많이 사용합니다. 4x4의 행렬을 이용하여 좌표정보를 기록하는 것입니다.
transmarix[] =
- -
| xresolution, 0 , 0, xorigin |
| 0 , yresoluion, 0, yorigin |
| 0 , 0 , 0, 0 |
| 0 , 0 , 0, 1 |
- _
(cols, rows, 0, 1)의 Image 좌표와 계산을 하면, 그 값들이 나옵니다.
사실 tranmatrix[1], transmatrix[4], 같은 경우는 0이 아닌 다른 값을 가질 수도 있습니다. 인터그라프에서 나오는 GeoTiff들이 이런 경우가 많지요. (그래서 악명이 높기도 하죠.) 이런 경우 많은 RS S/W 들이 파싱을 제대로 못하더군요.
GeoTiff가 원래 인터그라프로부터 시작됐음을 고려할 때 인정할 수 있는 부분이겠죠.
만약,
TIFFSetField(tif, TIFFTAG_GEOTRANSMATRIX, 16, transmatrix); 을 사용하시면,
TIFFSetField(tif,TIFFTAG_GEOTIEPOINTS, 6, tiepoints);
TIFFSetField(tif,TIFFTAG_GEOPIXELSCALE, 3, pixscale);
의 두가지는 사용하지 않으셔도 됩니다.
GeoTiff Library는 아시다시피 http://www.remotesensing.org/geotiff/ 에서 구하실 수 있습니다.
Tiff Library는 http://www.libtiff.org 에서 구하실 수 있습니다.
도움 되셨기를 빕니다만, 워낙 간략화해서 써놓아 도움이 될려는지 모르겠습니다.
그래도...
2001년 8월 22일
'공간정보와 IT' 카테고리의 다른 글
ERDAS 파일 포맷 사양서 (0) | 2007.10.18 |
---|---|
지도 투영과 좌표계 문서 하나 더 (0) | 2007.10.18 |
KATEC 좌표계 관련 자료 (0) | 2007.10.18 |
지도, 좌표계, 투영법 관련 PPT (0) | 2007.10.09 |
좌표계 변환 프로그램 C++ 소스(단일 좌표 및 파일 변환까지...) (8) | 2007.10.09 |
좌표변환프로그램 비주얼베이직소스 (10) | 2007.10.09 |
[SHPViewer 강좌 7] UTM 및 TM 투영법 클래스가 붙은 버젼 (0) | 2007.10.09 |
[SHPViewer 강좌 6] 공간인덱싱 - 1 (1) | 2007.10.09 |
[SHPViewer 강좌 5] Draw에 대해 (5) | 2007.10.09 |
[SHPViewer 강좌 4] SHPViewer 다음 버젼.. (0) | 2007.10.09 |