在GDAL庫中包含柵格資料的讀寫,向量資料的讀寫,以及柵格和向量資料的相關演算法。下面主要對GDAL中柵格資料和向量資料的體系架構做一個簡單的說明。本人英文很爛,有些部分寫出來的東西自己都看不懂,如果不懂,可以看英文。
一、GDAL體系架構
參考GDAL官方文檔:http://www.gdal.org/gdal_datamodel.html。
GDAL使用抽象資料模型(abstract data model)來解析它所支援的資料格式,抽象資料模型包括資料集(dataset),座標系統(Coordinate System),仿射地理座標轉換(Affine GeoTransform), 大地控制點(GCPs), 中繼資料(Metadata),子資料集域(Subdatasets Domain),映像結構域(Image_Structure Domain),RPC域(RPC
Domain),XML域(XML:Domains),柵格波段(Raster Band),顏色表(Color Table)和快視圖(Overviews)。
1、資料集(Dataset)
資料集是由柵格波段和一些相關的資訊共同組成的(具體參考GDALDataset類),在一個指定的資料集中所有的波段都具有相同的大小(映像行數和列數);資料集同時負責對所有的波段定義地理座標和投影等資訊;資料集中還有一些中繼資料資訊,這些資訊是由字串組成的一系列(名稱:值)的字串列表。
GDAL資料集是基於OpenGIS網格資料的說明來實現的。
2、座標系統(CoordinateSystem)
資料集中的座標系統是基於OpenGIS的WKT(WellKnown Text)字串格式的。裡麵包含下面內容:
- 座標系統名稱
- 地理座標系統名稱
- 大地水準面
- 托球體名稱,長半軸和扁率
- 中央經線名稱和與本初子午線的位移量
- 投影方式(如:橫軸墨卡托)
- 投影參數列表(如:中央經線)
- 單位名稱和與米或者弧度之間的轉換係數
- 名稱和座標軸順序
- 以上項對應的EPSG代碼
更多關於OpenGIS的WKT座標定義和相關資訊,可以參考文檔osr_tutorial。擷取座標系統可以使用函數 GDALDataset::GetProjectionRef(),如果該函數的傳回值為"",說明該映像沒有地理座標系統。
1、仿射地理座標轉換(Affine GeoTransform)
GDAL資料集有兩種方式來表示柵格行列號座標和地理座標之間的關係,第一種,也是最常用的,就是使用仿射變換來表示(另外一種是GCP點)。
仿射變換包含六個參數,可以使用函數 GDALDataset::GetGeoTransform()擷取,映像行列號和地理空間之間的變換關係如下:
Xgeo = GT(0) + Xpixel*GT(1) + Yline*GT(2)
Ygeo = GT(3) + Xpixel*GT(4) + Yline*GT(5)
在北方向上的映像中,參數GT(2)和GT(4)的值是0,GT(1)表示象元寬度,GT(5)表示象元高度。點 (GT(0),GT(3))表示映像左上方的橫縱座標值。
值得注意的是:行列號座標系統中,映像的(0.0,0.0)座標在映像的左上方,座標(象元寬個數,象元高個數)表示映像的右下角座標。映像的左上方象元的中心點座標是(0.5,0.5)。
2、大地控制點(GCPs)
資料集中可能會包括一系列的控制點,用來確定映像的地理參考座標。所有的控制點都是在同一個座標系統下的(可以使用函數GDALDataset::GetGCPProjection()來擷取該座標系),每一個GCP(使用GDAL_GCP類來表示)包括下面的內容:
typedef struct{ char *pszId; char *pszInfo; double dfGCPPixel; double dfGCPLine; double dfGCPX; double dfGCPY; double dfGCPZ;} GDAL_GCP;pszId字串表示一個唯一的字串,用來藐視在當前資料集中的GCP點中的具體的GCP點(通常情況下,可能是由數字構成,但不是所有的情況下)。pszInfo通常是一個Null 字元串,但是可以用來儲存使用者自訂用來描述GCP的文本資訊。很可能包含GCP的一些狀態資訊,如擷取時間等。
座標(Pixel,Line)表示GCP在映像上的位置,座標(X,Y,Z)表示在地理參考座標系中的位置,通常Z值是0。
GDAL資料模型中不會都包含GCP點構成的轉換方程,這個工作常常在應用程式中處理。通常使用1次到5次多項式進行轉換。
通常資料集包括一個仿射地理座標變換,GCP點可能會有,有時候這兩個都沒有。
3、中繼資料(Metadata)GDAL中繼資料是輔助格式和應用程式指定的資料使用一個名稱/值的點對列表。名稱需要能夠很好的表示其作用(不含有空格或者其他特殊字元)。值可以有任意長度,可以包括任何東西除了空值(ASCII的0值)。
中繼資料在系統中不能處理太大的資料,如果中繼資料超過100kb就會導致效能下降。
一些常用的的格式的中繼資料都可以支援,比如在TIFF驅動返回一些了標籤資訊作為中繼資料,比如日期/時間的形式如下:
TIFFTAG_DATETIME=1999:05:11 11:29:56
中繼資料可以按照名稱組來拆分為不同的域,預設域是沒有名稱的,如(NULL或者"")。一些特殊的域用於特殊的目的。
下面的中繼資料項目定義在預設的域中:
- AREA_OR_POINT: 可以是“Area”或者“Point”,預設為Area。表明一個像素值表示中心像元的像素值或者像元中心點的採樣值。但這並不影響整個地區的地理參考資訊。
- NODATA_VALUES:NODATA值。這個值是使用空格隔開的一系列的像素值,個數和波段數相同。使用這種方式是為了使所有波段都有一個NODATA值相匹配。這個中繼資料沒有廣泛的用於資料驅動,演算法或者工具集中。
- MATRIX_REPRESENTATION:這個值用來表示極化SAR資料集,包含矩陣表示的資料。矩陣可以用下面的值來進行表示:
- SCATTERING 散射
- SYMMETRIZED_SCATTERING 對稱散射
- COVARIANCE 共變數
- SYMMETRIZED_COVARIANCE 對稱共變數
- COHERENCY 相干
- SYMMETRIZED_COHERENCY 對稱相干
- KENNAUGH
- SYMMETRIZED_KENNAUGH
- POLARMETRIC_INTERP:這個中繼資料項用來定義多波段極化SAR資料的柵格波段。指定的矩陣表示這個波段的資料。資料集就是一個散射矩陣,比如,這個中繼資料可接受的值有,HH、HV、VH、VV四個。當資料集是一個共變數矩陣時,這個中繼資料將分別是Covariance_11、Covariance_22、Covariance_33、Covariance_12、Covariance_13、Covariance_23中的一個(因為這個矩陣本身就是一個Hermitian矩陣,即所有的資料都用來表示這個矩陣)。
4、子資料集域(Subdatasets Domain)
子資料集域中含有一個子資料集的列表。通常用來儲存在一個檔案的多個檔案(如HDF和NITF格式),例如,一個NITF格式的檔案中擷取子資料集的資訊如下:
SUBDATASET_1_NAME=NITF_IM:0:multi_1b.ntf
SUBDATASET_1_DESC=Image 1 of multi_1b.ntf
SUBDATASET_2_NAME=NITF_IM:1:multi_1b.ntf
SUBDATASET_2_DESC=Image 2 of multi_1b.ntf
SUBDATASET_3_NAME=NITF_IM:2:multi_1b.ntf
SUBDATASET_3_DESC=Image 3 of multi_1b.ntf
SUBDATASET_4_NAME=NITF_IM:3:multi_1b.ntf
SUBDATASET_4_DESC=Image 4 of multi_1b.ntf
SUBDATASET_5_NAME=NITF_IM:4:multi_1b.ntf
SUBDATASET_5_DESC=Image 5 of multi_1b.ntf
含有_NAME的字串,可以使用GDALOpen()函數來進行訪問子檔案。含有_DESC字串是用來方便的展示給使用者選擇哪個檔案。
5、映像結構域(Image_Structure Domain)
在預設域的中繼資料用來描述映像的相關資訊,這些中繼資料並沒有以特殊的方式儲存在磁碟中。意思就是說,當這些中繼資料資訊被複製到一個新的映像中的時候,會以合適的方式存在新的映像中。此外還有一些資訊是和映像的格式緊密關聯的。為了防止這些資訊在寫入新映像的時候被複製,將這些資訊儲存在一個叫IMAGE_STRUCTURE的特殊域中,通常這裡儲存的東西不會寫入到新的映像中去。
目標,在IMAGE_STRUCTURE域中定義的項目主要有下面幾個。
- COMPRESSION:壓縮方式用來指定資料集或者波段的壓縮方式,這個是沒有固定的壓縮類型名稱,但是一個指定的格式,如果指定壓縮方式,那麼在建立的時候會使用這種壓縮方式進行壓縮。
- NBITS:當前波段或者當前資料集的波段中真實的資料存放區bit數。通常只有非標準的資料類型才會使用該值,比如TIFF映像中的1bit資料,在GDAL會使用GDT_Byte來表示。
- INTERLEAVE:這個只能用在資料集中,用來表示一個像元,一行和一個波段之間的間隔,可以用來作為讀取資料的一個提示。
- PIXELTYPE:這個值會出現在一個GDT_Byte類型的波段(或者相應的資料集)中,並且會使用SIGNEDBYTE值來表示無符號byte值介於128和255之間值應該轉換為-128到-1之間。
6、RPC域(RPCDomain)
RPC中繼資料域儲存的是有理函數模型的係數,該模型表示從映像行列號與空間參考位置間的變換關係,該模型具體定義如下:
· ERR_BIAS: 位移誤差,映像上所有的點在水平軸上的位移的中誤差,-1.0表示未知。
· ERR_RAND: 隨機誤差,映像上所有的點在水平軸上的隨機中誤差,-1.0表示未知。
· LINE_OFF: 行位移量
· SAMP_OFF: 列位移量
· LAT_OFF: 緯度位移量
· LONG_OFF: 經度位移量
· HEIGHT_OFF: 高程位移量
· LINE_SCALE: 行縮放比例
· SAMP_SCALE: 列縮放比例
· LAT_SCALE: 緯度縮放比例
· LONG_SCALE: 經度縮放比例
· HEIGHT_SCALE: 高程縮放比例
· LINE_NUM_COEFF (1-20): 行分子係數,一共20個(使用空格隔開)
· LINE_DEN_COEFF (1-20): 行分母係數,一共20個(使用空格隔開)
· SAMP_NUM_COEFF (1-20): 列分子係數,一共20個(使用空格隔開)
· SAMP_DEN_COEFF (1-20): 列分母係數,一共20個(使用空格隔開)
這些內容都是來自GeoTIFF的RPC文檔(http://geotiff.maptools.org/rpc_prop.html)。
7、XML域(XML:Domains)
任何首碼是“xml:”的一個字串,但不是名稱/值這種類型的,這是一個簡單的XML格式的長字串。
8、柵格波段(Raster Band)
一個柵格波段在GDAL中使用GDALRasterBand類來進行表示。他表示一個柵格波段、通道或者圖層。波段不能完全用來表示整個映像,比如一個24位的RGB映像中就含有三個波段,分別是紅波段,綠波段和藍波段。
柵格波段含有下面屬性:
· 映像的寬和高,這個和資料集裡面的定義一樣,如果這個波段是全解析度波段的話。(這裡有個說明,GDALRasterBand還可以表示金字塔的波段,如果是金字塔的波段的話,裡面的寬高就和映像的寬高不一樣)。
· 資料類型(GDALDataType)。應該是Byte、UInt16、Int16、UInt32、Int32、Float32、Float64以及複數類型CInt16、CInt32、CFloat32和CFloat64中的一個。
· 塊大小。通過塊是讀取資料最高效的方式,對於分塊資料,就是一個分塊大小,對於大多數映像來說,一塊就是一行。
· 名稱/值的中繼資料對,格式和資料集中的一員,但是包含的資訊可能是波段特有的。
· 一個可選的波段描述字串。
· 一個可選的用來描述NODATA值的像元值。
· 一個可選的NODATA值表示的掩碼波段或者在某些時候作為透明通道。
· 可選的類別名稱列表(用於分類圖)
· 可選的最大值和最小值。
· 可選的位移量和縮放比例,用來對映像的像素值進行變換,比如變換高度到米等。
· 映像單位名稱,可選。比如可以用來表示高程資料的海拔。
· 波段的顏色資訊,是下面值中的某一個:
o GCI_Undefined:預設值,未知
o GCI_GrayIndex: 灰階映像
o GCI_PaletteIndex:顏色表映像
o GCI_RedBand: RGBA映像的R部分
o GCI_GreenBand: RGBA映像的G部分
o GCI_BlueBand: RGBA映像的B部分
o GCI_AlphaBand: RGBA映像的Alpha部分
o GCI_HueBand: HLS映像的色調部分
o GCI_SaturationBand: HLS映像的飽和度部分
o GCI_LightnessBand:HLS映像的亮度部分
o GCI_CyanBand: CMYK映像的青色部分
o GCI_MagentaBand: CMYK映像的品紅部分
o GCI_YellowBand: CMYK映像的黃色部分
o GCI_BlackBand: CMYK映像的黑色部。
· 顏色表,下面有更詳細的說明。
· 如果金字塔可用,含有一些關於金字塔的資訊。
9、顏色表(Color Table)
顏色表的定義如下,使用C語言的風格定義:
typedef struct{ /- gray, red, cyan or hue-/ short c1; /- green, magenta, orlightness -/ short c2; /- blue, yellow, orsaturation -/ short c3; /- alpha or blackband -/ short c4; } GDALColorEntry;顏色表通常是顏色調色盤的一個值,對於c1/c2/c3/c4 四個值對應不同的調色盤,其表示的含義不同,具體表示見下:
l GPI_Gray: 使用c1表示灰階值。
l GPI_RGB: c1表示紅色,c2表示綠色,c3表示藍色,c4表示alpha通道。
l GPI_CMYK: c1表示青色,c2表示洋紅,c3表示黃色,c4表示黑色。
l GPI_HLS: c1表示色調,c2表示亮度,c3表示飽和度。
通過顏色表,將象元值用顏色表中的顏色來進行表示,顏色表中的值是從0開始遞增。
10、快視圖(Overviews)
一個波段中可能沒有或者有很多個快視圖。每個快視圖都是一個GDALRasterBand,略縮圖大小將和其下層的柵格大小不一樣,但是快視圖表示的地區與整個映像的地區是一致的。
快視圖是用來快速顯示映像用的,使用全解析度映像進行降採樣得到。
波段可以通過函數HasArbitraryOverviews,返回TRUE表示可以快速讀取任何解析度的快視圖,這個主要應用在一些如FFT編碼的映像(這句有點彆扭,自己看英文原文吧)。
11、GDAL核心類結構設計
GDAL的核心類結構設計:
其中的類說明如下:
GDALMajorObject類:帶有中繼資料的對象。
GDALDdataset類:通常是從一個柵格檔案中提取的相關聯的柵格波段集合和這些波段的中繼資料;GDALDdataset也負責所有柵格波段的地理座標轉換(georeferencingtransform)和座標系定義。
GDALDriver類:檔案格式驅動類,GDAL會為每一個所支援的檔案格式建立一個該類的實體,來管理該檔案格式。
GDALDriverManager類:檔案格式驅動管理類,用來管理GDALDriver類。
二、OGR體系架構1、OGR體繫結構
OGR包括如下幾部分:
Geometry:類Geometry (包括OGRGeometry等類)封裝了OpenGIS的向量資料模型,並提供了一些幾何操作,WKB(Well Knows Binary)和WKT(Well Known Text)格式之間的相互轉換,以及空間參考系統(投影)。
Spatial Reference:類OGRSpatialReference封裝了投影和基準面的定義。
Feature:類OGRFeature封裝了一個完整feature的定義,一個完整的feature包括一個geometry和geometry的一系列屬性。
Feature Definition:類OGRFeatureDefn裡面封裝了feature的屬性,類型、名稱及其預設的空間參考系統等。一個OGRFeatureDefn對象通常與一個層(layer)對應。
Layer:類OGRLayer是一個抽象基類,表示資料來源類OGRDataSource裡面的一層要素(feature)。
Data Source:類OGRDataSource是一個抽象基類,表示含有OGRLayer對象的一個檔案或一個資料庫。
Drivers:類OGRSFDriver對應於每一個所支援的向量檔案格式。類OGRSFDriver由類OGRSFDriverRegistrar來註冊和管理。
2、OGR的Geometry模型
OGR的Geometry模型是建立在OpenGIS的簡單要素資料模型之上的。如所示:
圖-OGR的Geometry模型關係圖
OpenGIS的簡單要素資料模型,其關係圖如下所示:
圖-OpenGIS的簡單要素資料模型
由上面兩圖的對比,可以清楚的看到,OGR的Geometry模型是嚴格遵循OpenGIS的簡單要素資料規範的。OGR的Geometry模型不僅在繼承體繫上與OpenGIS的簡單要素資料模型一致,在函數介面上也向其靠攏,從基本的擷取Geometry對象資訊的方法如Dimension ()、GeometryType ()、SRID ()、Envelope()、AsText()、Boundary()等到判定空間未知關係的方法如Equals(anotherGeometry:Geometry)、Disjoint(anotherGeometry:Geometry)、
Intersects(anotherGeometry:Geometry)、Touches(anotherGeometry:Geometry)等都是符合其標準的。
對於OGR庫後面會專門進行說明,這裡簡單說明一下就好。