📄 gdal_drivertut.html
字号:
// Try to create the file. // -------------------------------------------------------------------- FILE *fp; fp = VSIFOpen( pszFilename, "w" ); if( fp == NULL ) { CPLError( CE_Failure, CPLE_OpenFailed, "Attempt to create file `%s' failed.\n", pszFilename ); return NULL; }// -------------------------------------------------------------------- // Just write out a couple of bytes to establish the binary // file, and then close it. // -------------------------------------------------------------------- VSIFWrite( (void *) "\0\0", 2, 1, fp ); VSIFClose( fp );// -------------------------------------------------------------------- // Create the aux filename. // -------------------------------------------------------------------- pszAuxFilename = (char *) CPLMalloc(strlen(pszFilename)+5); strcpy( pszAuxFilename, pszFilename );; for( int i = strlen(pszAuxFilename)-1; i > 0; i-- ) { if( pszAuxFilename[i] == '.' ) { pszAuxFilename[i] = '\0'; break; } } strcat( pszAuxFilename, ".aux" );// -------------------------------------------------------------------- // Open the file. // -------------------------------------------------------------------- fp = VSIFOpen( pszAuxFilename, "wt" ); if( fp == NULL ) { CPLError( CE_Failure, CPLE_OpenFailed, "Attempt to create file `%s' failed.\n", pszAuxFilename ); return NULL; } // -------------------------------------------------------------------- // We need to write out the original filename but without any // path components in the AuxilaryTarget line. Do so now. // -------------------------------------------------------------------- int iStart; iStart = strlen(pszFilename)-1; while( iStart > 0 && pszFilename[iStart-1] != '/' && pszFilename[iStart-1] != '\\' ) iStart--; VSIFPrintf( fp, "AuxilaryTarget: %s\n", pszFilename + iStart );// -------------------------------------------------------------------- // Write out the raw definition for the dataset as a whole. // -------------------------------------------------------------------- VSIFPrintf( fp, "RawDefinition: %d %d %d\n", nXSize, nYSize, nBands );// -------------------------------------------------------------------- // Write out a definition for each band. We always write band // sequential files for now as these are pretty efficiently // handled by GDAL. // -------------------------------------------------------------------- int nImgOffset = 0; for( int iBand = 0; iBand < nBands; iBand++ ) { const char * pszTypeName; int nPixelOffset; int nLineOffset; nPixelOffset = GDALGetDataTypeSize(eType)/8; nLineOffset = nXSize * nPixelOffset; if( eType == GDT_Float32 ) pszTypeName = "32R"; else if( eType == GDT_Int16 ) pszTypeName = "16S"; else if( eType == GDT_UInt16 ) pszTypeName = "16U"; else pszTypeName = "8U"; VSIFPrintf( fp, "ChanDefinition-%d: %s %d %d %d %s\n", iBand+1, pszTypeName, nImgOffset, nPixelOffset, nLineOffset,#ifdef CPL_LSB "Swapped"#else "Unswapped"#endif ); nImgOffset += nYSize * nLineOffset; }// -------------------------------------------------------------------- // Cleanup // -------------------------------------------------------------------- VSIFClose( fp ); return (GDALDataset *) GDALOpen( pszFilename, GA_Update );}</pre></div><p>File formats supporting dynamic creation, or even just update-in-place access also need to implement an IWriteBlock() method on the raster band class. It has semantics similar to IReadBlock(). As well, for various esoteric reasons, it is critical that a FlushCache() method be implemented in the raster band destructor. This is to ensure that any write cache blocks for the band be flushed out before the destructor is called.<h2><a class="anchor" name="gdal_drivertut_raw">RawDataset/RawRasterBand Helper Classes</a></h2>Many file formats have the actual imagery data stored in a regular, binary, scanline oriented format. Rather than re-implement the access semantics for this for each formats, there are provided RawDataset and RawRasterBand classes declared in gdal/frmts/raw that can be utilized to implement efficient and convenient access.<p>In these cases the format specific band class may not be required, or if required it can be derived from RawRasterBand. The dataset class should be derived from RawDataset.<p>The Open() method for the dataset then instantiates raster bands passing all the layout information to the constructor. For instance, the PNM driver uses the following calls to create it's raster bands.<p><div class="fragment"><pre class="fragment"> <span class="keywordflow">if</span>( poOpenInfo->pabyHeader[1] == <span class="charliteral">'5'</span> ) { poDS->SetBand( 1, <span class="keyword">new</span> RawRasterBand( poDS, 1, poDS->fpImage, iIn, 1, nWidth, <a class="code" href="gdal_8h.html#22e22ce0a55036a96f652765793fb7a438a66c26861d368e95ba42106ee3ab92">GDT_Byte</a>, TRUE )); } <span class="keywordflow">else</span> { poDS->SetBand( 1, <span class="keyword">new</span> RawRasterBand( poDS, 1, poDS->fpImage, iIn, 3, nWidth*3, <a class="code" href="gdal_8h.html#22e22ce0a55036a96f652765793fb7a438a66c26861d368e95ba42106ee3ab92">GDT_Byte</a>, TRUE )); poDS->SetBand( 2, <span class="keyword">new</span> RawRasterBand( poDS, 2, poDS->fpImage, iIn+1, 3, nWidth*3, <a class="code" href="gdal_8h.html#22e22ce0a55036a96f652765793fb7a438a66c26861d368e95ba42106ee3ab92">GDT_Byte</a>, TRUE )); poDS->SetBand( 3, <span class="keyword">new</span> RawRasterBand( poDS, 3, poDS->fpImage, iIn+2, 3, nWidth*3, <a class="code" href="gdal_8h.html#22e22ce0a55036a96f652765793fb7a438a66c26861d368e95ba42106ee3ab92">GDT_Byte</a>, TRUE )); }</pre></div><p>The RawRasterBand takes the following arguments.<p><ul><li><b>poDS</b>: The <a class="el" href="classGDALDataset.html">GDALDataset</a> this band will be a child of. This dataset must be of a class derived from RawRasterDataset. </li><li><b>nBand</b>: The band it is on that dataset, 1 based. </li><li><b>fpRaw</b>: The FILE * handle to the file containing the raster data. </li><li><b>nImgOffset</b>: The byte offset to the first pixel of raster data for the first scanline. </li><li><b>nPixelOffset</b>: The byte offset from the start of one pixel to the start of the next within the scanline. </li><li><b>nLineOffset</b>: The byte offset from the start of one scanline to the start of the next. </li><li><b>eDataType</b>: The GDALDataType code for the type of the data on disk. </li><li><b>bNativeOrder</b>: FALSE if the data is not in the same endianness as the machine GDAL is running on. The data will be automatically byte swapped. </li></ul><p>Simple file formats utilizing the Raw services are normally placed all within one file in the gdal/frmts/raw directory. There are numerous examples there of format implementation.<h2><a class="anchor" name="gdal_drivertut_metadata">Metadata, and Other Exotic Extensions</a></h2>There are various other items in the GDAL data model, for which virtual methods exist on the <a class="el" href="classGDALDataset.html">GDALDataset</a> and <a class="el" href="classGDALRasterBand.html">GDALRasterBand</a>. They include:<p><ul><li><b>Metadata</b>: Name/value text values about a dataset or band. The <a class="el" href="classGDALMajorObject.html">GDALMajorObject</a> (base class for <a class="el" href="classGDALRasterBand.html">GDALRasterBand</a> and <a class="el" href="classGDALDataset.html">GDALDataset</a>) has built-in support for holding metadata, so for read access it only needs to be set with calls to SetMetadataItem() during the Open(). The SAR_CEOS (frmts/ceos2/sar_ceosdataset.cpp) and GeoTIFF drivers are examples of drivers implementing readable metadata.<p></li><li><b>ColorTables</b>: GDT_Byte raster bands can have color tables associated with them. The frmts/png/pngdataset.cpp driver contains an example of a format that supports colortables.<p></li><li><b>ColorInterpretation</b>: The PNG driver contains an example of a driver that returns an indication of whether a band should be treated as a Red, Green, Blue, Alpha or Greyscale band.<p></li><li><b>GCPs</b>: GDALDatasets can have a set of ground control points associated with them (as opposed to an explicit affine transform returned by GetGeotransform()) relating the raster to georeferenced coordinates. The MFF2 (gdal/frmts/raw/hkvdataset.cpp) format is a simple example of a format supporting GCPs.<p></li><li><b>NoDataValue</b>: Bands with known "nodata" values can implement the GetNoDataValue() method. See the PAux (frmts/raw/pauxdataset.cpp) for an example of this.<p></li><li><b>Category Names</b>: Classified images with names for each class can return them using the GetCategoryNames() method though no formats currently implement this.<p></li></ul><p> <p>$Id: gdal_drivertut.dox 10112 2006-10-18 13:26:46Z mloskot $</p> <hr>Generated for GDAL by <a href="http://www.doxygen.org/index.html"><img src="doxygen.png" alt="doxygen" align="middle" border="0"></a> 1.5.1.</body></html>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -