GeoTiff探索成果總結 (轉)
GeoTiff探索成果總結
to:cixiaoyong@21cn.com">cixiaoyong@21cn.com
GeoTiff是包含地理資訊的一種Tiff格式的。記得數月前在CSDN論壇上提問過關於GeoTiff檔案讀寫的問題,回答者了了,偶有回答都限於“只是Tiff檔案加幾個標籤而已……”云云,而當我對此做了一番深入研究之後,發現儘管GeoTiff確實只是Tiff的一種特例,但要遵循規範來用好它卻絕不是那麼簡單,在此我準備將自己的學習做一個小結,以期深入交流。:namespace prefix = o ns = "urn:schemas--com::office" />
1 GeoTiff利用Tiff表達Geo(地理)資訊的思想
Tiff對GeoTiff的支援已寫進Tiff6.0,也就是說,GeoTiff是一種Tiff6.0檔案,它繼承了在Tiff6.0規範中的相應部分,所有的GeoTiff特有的資訊都編碼在Tiff的一些預留Tag(標籤)中,它沒有自己的IFD(影像檔案目錄)、二進位制結構以及其它一些對Tiff來說不可見的資訊。
用來描述GeoTiff流行的眾多影射引數及型別資訊,如果每一個資訊都採用一個標籤那將至少需要幾十甚至幾百個標籤,這會耗盡Tiff定義的有限的標籤資源,另一方面,雖然私有的IFD提供了數千個自由的標籤,但也是有限的,因為標籤值對不理解的讀者來說是不可見的(因為他們不知道IFD_OFFSET標籤值指向一個私有的IFD)。
為了避免這些問題,GeoTiff採用一系列的Keys(鍵)來存取這些資訊,這些鍵在功能上相當於標籤,但它處在TIFF上抽象更上一層。準確的說它是一種媒介標籤(Meta-Tag)。鍵與格式化的標籤值一起共存,TIFF其它影像資料。和標籤一樣,鍵也有的ID號,範圍從0到65535,但不像標籤那樣,所有鍵的ID號都可以用於GeoTiff的引數定義上。
2 結構與定義
這些鍵也稱為GeoKeys,所有鍵都由GeoKeyDirectoryTag標籤來,該標籤就相當於表示Geo資訊的鍵的一個目錄。它的結構如下:
GeoKeyDirectoryTag:
Tag = 34735 (87AF.H)
Type = SHORT (2-byte unsigned short)
N = variable, >= 4
Alias: ProjectionInfoTag, CoordSystemInfoTag
Owner: SPOT Image, Inc.
它由頭和鍵實體構成,如下:
Header={KeyDirectoryVersion, KeyRevision, MinorRevision, NumberOfKeys}
KeyEntry = { KeyID, TIFFTagLocation, Count, Value_Offset }
其中,TIFFTagLocation表示哪個tag存放值,如果值為0則表示值為SHORT型別且包含在Value_Offset元素中;否則,其值型別由tag含有值的TIFF-Type暗指。
所有Key值不是short型別的都存放在下面兩種Tag下,基於下面的結構:
GeoDoubleParamsTag:
Tag = 34736 (87BO.H)
Type = DOUBLE (IEEE Double precision)
N = variable
Owner: SPOT Image, Inc.
注:該tag用來存放DOUBLE型的GeoKeys,被GeoKeyDirectoryTag引用,這個double陣列中任何值的意義由指向它的GeoKeyDirectoryTag引用決定。FLOAT值必須先轉換為DOUBLE才能。
GeoAsciiParamsTag:
Tag = 34737 (87B1.H)
Type = ASCII
Owner: SPOT Image, Inc.
N = variable
例:
GeoKeyDirectoryTag=( 1, 1, 2, 6,
1024, 0, 1, 2,
1026, 34737,12, 0,
2048, 0, 1, 32767,
2049, 34737,14, 12,
2050, 0, 1, 6,
2051, 34736, 1, 0 )
GeoDoubleParamsTag(34736)=(1.5)
GeoAsciiParamsTag(34737)=("Custom File|My Geographic|")
第一行表明這是一個版本號為1的GeoTIFF GeoKey目錄,鍵的版本為Rev. 1.2,在這個標籤中定義了6個鍵。
下一行定義第一個鍵(ID=1024 = GTModelTypeGeoKey),值為2(Geographic),直接放在元素列表中(因為TIFFTagLocation=0);
下一行鍵1026(the GTCitationGeoKey),列在GeoAsciiParamsTag(34737)陣列中開始於偏移0,數到第12個位元組,所以其值為"Custom File"(”|”被轉換為結束符了)
再下面一行,鍵2051(GeogLinearUnitSizeGeoKey) 位於GeoDoubleParamsTag
(34736), 偏移為0所以值為1.5
key2049的值為(GeogCitationGeoKey) is "My Geographic"。
3 GeoTIFF中座標系
Geotiff設計使得標準的地圖座標系定義可以以一個單一的註冊的標籤的形式隨意儲存。也支援非標準座標系的描述,為了在不同的座標系間轉換,可以透過使用三四個另設的TIFF標籤來實現。
然而,為了在各種不同的客戶端和GeoTIFF提供者間正確,最好要建立一個通能的來描述地圖投影。
在TIFF/GeoTIFF下,主要有3種不同的空間可供座標系定義,這3種空間是:
1. 光柵空間(影像空間)R,用於在一幅影像中表示象素值;
a) 在標準TIFF6.0中定義了與光柵空間R與裝置空間相關的標籤:如顯示器、掃描器、或印表機
2. 裝置空間D;
3. 模型空間M,用於表示地球上的點。
a) 地理座標系
b) 地心座標系
c) 投影座標系
d) 垂直座標系
下面是從GeoTIFF的觀點上來看,這3種空間的使用以及它們相應的座標系。
4 讀寫
講到這兒,我們得開始玩玩真的了,看我們如何來讀寫這類GeoTiff檔案的,我們的目標只有一個,我們將規範中要求的鍵值寫入檔案並能讀出,所幸的事,這些工作別人已經做了,這就是著名的LibGeoTiff,它是在LibTiff基礎上實現的。
它的主要讀寫原型如下:
- /geotiff_h.html#a19">GTIFFree(): Free GeoTIFF access handle.
- (): Read and Normalize GeoTIFF Definition.
- (): Read GeoTIFF GeoKey.
- (): Write GeoTIFF GeoKey.
- (): Create GeoTIFF access handle.
- (): Flush GeoTIFF Keys.
- (): Overr CSV File Searching.
- (): Close GeoTIFF file.
- (): Open GeoTIFF file.
下面是一個例程makegeo.c:
/*
* makegeo.c -- example client code for LIBGEO geographic
* TIFF tag support.
*
* Author: Niles D. Ritter
*
* Revision History:
* 31 October, 1995 Fixed reversed lat-long coordinates NDR
*
*/
#include "geotiffio.h"
#include "xtiffio.h"
#include
void SetUpTIFFDirectory(TIFF *tif);
void SetUpGeoKeys(GTIF *gtif);
void WriteImage(TIFF *tif);
#define WIDTH 20L
#define HEIGHT 20L
void main()
{
char *fname = "newgeo.tif";
TIFF *tif=(TIFF*)0; /* TIFF-level descriptor */
GTIF *gtif=(GTIF*)0; /* GeoKey-level descriptor */
tif=XTIFFOpen(fname,"w");
if (!tif) goto failure;
gtif = GTIFNew(tif);
if (!gtif)
{
printf("failed in GTIFNew ");
goto failure;
}
SetUpTIFFDirectory(tif);
SetUpGeoKeys(gtif);
WriteImage(tif);
GTIFWriteKeys(gtif);
GTIFFree(gtif);
XTIFFClose(tif);
exit (0);
failure:
printf("failure in makegeo ");
if (tif) TIFFClose(tif);
if (gtif) GTIFFree(gtif);
exit (-1);
}
void SetUpTIFFDirectory(TIFF *tif)
{
double tiepoints[6]={0,0,0,130.0,32.0,0.0};
double pixscale[3]={1,1,0};
TIFFSetField(tif,TIFFTAG_IMAGEWIDTH, WIDTH);
TIFFSetField(tif,TIFFTAG_IMAGELENGTH, HEIGHT);
TIFFSetField(tif,TIFFTAG_COMPRESSION, COMPRESSION_NONE);
TIFFSetField(tif,TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_MINISBLACK);
TIFFSetField(tif,TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG);
TIFFSetField(tif,TIFFTAG_BITSPERSAMPLE, 8);
TIFFSetField(tif,TIFFTAG_ROWSPERSTRIP, 20L);
TIFFSetField(tif,TIFFTAG_GEOTIEPOINTS, 6,tiepoints);
TIFFSetField(tif,TIFFTAG_GEOPIXELSCALE, 3,pixscale);
}
void SetUpGeoKeys(GTIF *gtif)
{
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);
}
void WriteImage(TIFF *tif)
{
int i;
char buffer[WIDTH];
memset(buffer,0,(size_t)WIDTH);
for (i=0;i if (!TIFFWriteScanline(tif, buffer, i, 0)) TIFFError("WriteImage","failure in WriteScanline
"); } 本次行文倉促,主要想著早點和大家交流,希望多提意見,我會不斷修改整理這方面內容。 P.S.本文版權所有,未經允許,不得轉載或它用.
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/10752043/viewspace-963665/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- web AR探索和總結Web
- 最近幾天玩freebsd奮鬥成果總結
- javaSE總結(轉+總結)Java
- 探索性測試總結筆記筆記
- 轉:Git 總結Git
- SmartForms總結(轉)ORM
- 對api請求封裝的探索和總結API封裝
- 2017前端監控系統探索總結前端
- Android探索之Service全面回顧及總結Android
- IOCP模型總結(轉)模型
- TTS的總結 (轉)TTS
- Enqueue整理總結(轉)ENQ
- 9.9~9.15號學習成果彙總
- 分享我的:領域驅動設計(DDD)學習成果精簡總結
- ANT命令總結(轉載)
- Oracle 行列轉換總結Oracle
- oracle 轉義字元 總結Oracle字元
- ORACLE壞塊總結(轉)Oracle
- 個人工作總結(轉)
- Oracle 9.2.0.4 DataGuard 總結(轉)Oracle
- Oracle行列轉換總結Oracle
- RMAN 總結篇 1 - (轉)
- RMAN 總結篇 2 - (轉)
- RMAN 總結篇 3 - (轉)
- android WebView總結(轉)AndroidWebView
- Facebook全年成果總結:我們在AI領域的行動從未停止AI
- 2023年終總結:拉幫結夥,拼搏探索新機遇
- SAP轉儲單全面總結
- 【轉】Qt資料庫總結QT資料庫
- 清除浮動方法總結(轉)
- 轉載關於JOIN總結
- oracle分割槽表總結(轉)Oracle
- PLSQL開發精品總結(轉)SQL
- 行列轉換問題總結
- 轉載:CSS垂直居中總結CSS
- ORACLE 中ROWNUM用法總結! (轉)Oracle
- 程式設計之美(第3章 結構之法-字串及連結串列的探索)總結程式設計字串
- Vue2.0 探索之路——vue-router入門教程和總結Vue