⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 gdal_drivertut.html

📁 gdal库的学习文档
💻 HTML
📖 第 1 页 / 共 4 页
字号:
This completes explanation of the features of the JDEM driver. The full source for <a href="jdemdataset.cpp.html">jdemdataset.cpp</a> can be reviewed as needed.<h2><a class="anchor" name="gdal_drivertut_overviews">Overviews</a></h2>GDAL allows file formats to make pre-built overviews available to applications via the <a class="el" href="classGDALRasterBand.html#2ab58ccaef2a64ad938cd69973c6ace1">GDALRasterBand::GetOverview()</a> and related methods. However, implementing this is pretty involved, and goes beyond the scope of this document for now. The GeoTIFF driver (gdal/frmts/gtiff/geotiff.cpp) and related source can be reviewed for an example of a file format implementing overview reporting and creation support.<p>Formats can also report that they have arbitrary overviews, by overriding the HasArbitraryOverviews() method on the <a class="el" href="classGDALRasterBand.html">GDALRasterBand</a>, returning TRUE. In this case the raster band object is expected to override the RasterIO() method itself, to implement efficient access to imagery with resampling. This is also involved, and there are a lot of requirements for correct implementation of the RasterIO() method. An example of this can be found in the OGDI and ECW formats.<p>However, by far the most common approach to implementing overviews is to use the default support in GDAL for external overviews stored in TIFF files with the same name as the dataset, but the extension .ovr appended. In order to enable reading and creation of this style of overviews it is necessary for the <a class="el" href="classGDALDataset.html">GDALDataset</a> to initialize the oOvManager object within itself. This is typically accomplished with a call like the following near the end of the Open() method.<p><div class="fragment"><pre class="fragment">    poDS-&gt;oOvManager.Initialize( poDS, poOpenInfo-&gt;pszFilename );</pre></div><p>This will enable default implementations for reading and creating overviews for the format. It is advised that this be enabled for all simple file system based formats unless there is a custom overview mechanism to be tied into.<h2><a class="anchor" name="gdal_drivertut_creation">File Creation</a></h2>There are two approaches to file creation. The first method is called the CreateCopy() method, and involves implementing a function that can write a file in the output format, pulling all imagery and other information needed from a source <a class="el" href="classGDALDataset.html">GDALDataset</a>. The second method, the dynamic creation method, involves implementing a Create method to create the shell of the file, and then the application writes various information by calls to set methods.<p>The benefits of the first method are that that all the information is available at the point the output file is being created. This can be especially important when implementing file formats using external libraries which require information like colormaps, and georeferencing information at the point the file is created. The other advantage of this method is that the CreateCopy() method can read some kinds of information, such as min/max, scaling, description and GCPs for which there are no equivalent set methods.<p>The benefits of the second method are that applications can create an empty new file, and write results to it as they become available. A complete image of the desired data does not have to be available in advance.<p>For very important formats both methods may be implemented, otherwise do whichever is simpler, or provides the required capabilities.<h3><a class="anchor" name="gdal_drivertut_creation_createcopy">CreateCopy</a></h3>The <a class="el" href="classGDALDriver.html#d0f7a33b0bd7f9d685bbd90d04fde629">GDALDriver::CreateCopy()</a> method call is passed through directly, so that method should be consulted for details of arguments. However, some things to keep in mind are:<p><ul><li>If the bStrict flag is FALSE the driver should try to do something reasonable when it cannot exactly represent the source dataset, transforming data types on the fly, dropping georeferencing and so forth.<p></li><li>Implementing progress reporting correctly is somewhat involved. The return result of the progress function needs always to be checked for cancellation, and progress should be reported at reasonable intervals. The JPEGCreateCopy() method demonstrates good handling of the progress function.<p></li><li>Special creation options should be documented in the online help. If the options take the format "NAME=VALUE" the papszOptions list can be manipulated with CPLFetchNameValue() as demonstrated in the handling of the QUALITY and PROGRESSIVE flags for JPEGCreateCopy().<p></li><li>The returned <a class="el" href="classGDALDataset.html">GDALDataset</a> handle can be in ReadOnly or Update mode. Return it in Update mode if practical, otherwise in ReadOnly mode is fine.<p></li></ul><p>The full implementation of the CreateCopy function for JPEG (which is assigned to pfnCreateCopy in the <a class="el" href="classGDALDriver.html">GDALDriver</a> object) is here.<p><div class="fragment"><pre class="fragment">static GDALDataset *JPEGCreateCopy( const char * pszFilename, GDALDataset *poSrcDS,                 int bStrict, char ** papszOptions,                 GDALProgressFunc pfnProgress, void * pProgressData ){    int  nBands = poSrcDS-&gt;GetRasterCount();    int  nXSize = poSrcDS-&gt;GetRasterXSize();    int  nYSize = poSrcDS-&gt;GetRasterYSize();    int  nQuality = 75;    int  bProgressive = FALSE;// -------------------------------------------------------------------- //      Some some rudimentary checks                                    // --------------------------------------------------------------------     if( nBands != 1 &amp;&amp; nBands != 3 )    {        CPLError( CE_Failure, CPLE_NotSupported,                   "JPEG driver doesn't support %d bands.  Must be 1 (grey) "                  "or 3 (RGB) bands.\n", nBands );        return NULL;    }    if( poSrcDS-&gt;GetRasterBand(1)-&gt;GetRasterDataType() != GDT_Byte &amp;&amp; bStrict )    {        CPLError( CE_Failure, CPLE_NotSupported,                   "JPEG driver doesn't support data type %s. "                  "Only eight bit byte bands supported.\n",                   GDALGetDataTypeName(                       poSrcDS-&gt;GetRasterBand(1)-&gt;GetRasterDataType()) );        return NULL;    }// -------------------------------------------------------------------- //      What options has the user selected?                             // --------------------------------------------------------------------     if( CSLFetchNameValue(papszOptions,"QUALITY") != NULL )    {        nQuality = atoi(CSLFetchNameValue(papszOptions,"QUALITY"));        if( nQuality &lt; 10 || nQuality &gt; 100 )        {            CPLError( CE_Failure, CPLE_IllegalArg,                      "QUALITY=%s is not a legal value in the range 10-100.",                      CSLFetchNameValue(papszOptions,"QUALITY") );            return NULL;        }    }    if( CSLFetchNameValue(papszOptions,"PROGRESSIVE") != NULL )    {        bProgressive = TRUE;    }// -------------------------------------------------------------------- //      Create the dataset.                                             // --------------------------------------------------------------------     FILE	*fpImage;    fpImage = VSIFOpen( pszFilename, "wb" );    if( fpImage == NULL )    {        CPLError( CE_Failure, CPLE_OpenFailed,                   "Unable to create jpeg file %s.\n",                   pszFilename );        return NULL;    }// -------------------------------------------------------------------- //      Initialize JPG access to the file.                              // --------------------------------------------------------------------     struct jpeg_compress_struct sCInfo;    struct jpeg_error_mgr sJErr;        sCInfo.err = jpeg_std_error( &amp;sJErr );    jpeg_create_compress( &amp;sCInfo );        jpeg_stdio_dest( &amp;sCInfo, fpImage );        sCInfo.image_width = nXSize;    sCInfo.image_height = nYSize;    sCInfo.input_components = nBands;    if( nBands == 1 )    {        sCInfo.in_color_space = JCS_GRAYSCALE;    }    else    {        sCInfo.in_color_space = JCS_RGB;    }    jpeg_set_defaults( &amp;sCInfo );        jpeg_set_quality( &amp;sCInfo, nQuality, TRUE );    if( bProgressive )        jpeg_simple_progression( &amp;sCInfo );    jpeg_start_compress( &amp;sCInfo, TRUE );// -------------------------------------------------------------------- //      Loop over image, copying image data.                            // --------------------------------------------------------------------     GByte 	*pabyScanline;    CPLErr      eErr;    pabyScanline = (GByte *) CPLMalloc( nBands * nXSize );    for( int iLine = 0; iLine &lt; nYSize; iLine++ )    {        JSAMPLE      *ppSamples;        for( int iBand = 0; iBand &lt; nBands; iBand++ )        {            GDALRasterBand * poBand = poSrcDS-&gt;GetRasterBand( iBand+1 );            eErr = poBand-&gt;RasterIO( GF_Read, 0, iLine, nXSize, 1,                                      pabyScanline + iBand, nXSize, 1, GDT_Byte,                                     nBands, nBands * nXSize );        }        ppSamples = pabyScanline;        jpeg_write_scanlines( &amp;sCInfo, &amp;ppSamples, 1 );    }    CPLFree( pabyScanline );    jpeg_finish_compress( &amp;sCInfo );    jpeg_destroy_compress( &amp;sCInfo );    VSIFClose( fpImage );    return (GDALDataset *) GDALOpen( pszFilename, GA_ReadOnly );}</pre></div><h3><a class="anchor" name="gdal_drivertut_creation_create">Dynamic Creation</a></h3>In the case of dynamic creation, there is no source dataset. Instead the size, number of bands, and pixel data type of the desired file is provided but other information (such as georeferencing, and imagery data) would be supplied later via other method calls on the resulting <a class="el" href="classGDALDataset.html">GDALDataset</a>.<p>The following sample implement PCI .aux labelled raw raster creation. It follows a common approach of creating a blank, but valid file using non-GDAL calls, and then calling GDALOpen(,GA_Update) at the end to return a writable file handle. This avoids having to duplicate the various setup actions in the Open() function.<p><div class="fragment"><pre class="fragment">GDALDataset *PAuxDataset::Create( const char * pszFilename,                                  int nXSize, int nYSize, int nBands,                                  GDALDataType eType,                                  char ** // papszParmList  ){    char	*pszAuxFilename;// -------------------------------------------------------------------- //      Verify input options.                                           // --------------------------------------------------------------------     if( eType != GDT_Byte &amp;&amp; eType != GDT_Float32 &amp;&amp; eType != GDT_UInt16        &amp;&amp; eType != GDT_Int16 )    {        CPLError( CE_Failure, CPLE_AppDefined,              "Attempt to create PCI .Aux labelled dataset with an illegal\n"              "data type (%s).\n",              GDALGetDataTypeName(eType) );        return NULL;    }// -------------------------------------------------------------------- 

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -