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

📄 gdal_drivertut.html

📁 gdal库的学习文档
💻 HTML
📖 第 1 页 / 共 4 页
字号:
<p>The full set of possible GDALDataType values are declared in <a class="el" href="gdal_8h.html">gdal.h</a>, and include GDT_Byte, GDT_UInt16, GDT_Int16, and GDT_Float32. The block size is used to establish a <em>natural</em> or efficient block size to access the data with. For tiled datasets this will be the size of a tile, while for most other datasets it will be one scanline, as in this case.<p>Next we see the implementation of the code that actually reads the image data, IReadBlock().<p><div class="fragment"><pre class="fragment">CPLErr JDEMRasterBand::IReadBlock( <span class="keywordtype">int</span> nBlockXOff, <span class="keywordtype">int</span> nBlockYOff,                                  <span class="keywordtype">void</span> * pImage ){    JDEMDataset *poGDS = (JDEMDataset *) poDS;    <span class="keywordtype">char</span>        *pszRecord;    <span class="keywordtype">int</span>         nRecordSize = nBlockXSize*5 + 9 + 2;    <span class="keywordtype">int</span>         i;    VSIFSeek( poGDS-&gt;fp, 1011 + nRecordSize*nBlockYOff, SEEK_SET );    pszRecord = (<span class="keywordtype">char</span> *) CPLMalloc(nRecordSize);    VSIFRead( pszRecord, 1, nRecordSize, poGDS-&gt;fp );    <span class="keywordflow">if</span>( !EQUALN((<span class="keywordtype">char</span> *) poGDS-&gt;abyHeader,pszRecord,6) )    {        CPLFree( pszRecord );        CPLError( CE_Failure, CPLE_AppDefined,                   <span class="stringliteral">"JDEM Scanline corrupt.  Perhaps file was not transferred\n"</span>                  <span class="stringliteral">"in binary mode?"</span> );        <span class="keywordflow">return</span> CE_Failure;    }        <span class="keywordflow">if</span>( JDEMGetField( pszRecord + 6, 3 ) != nBlockYOff + 1 )    {        CPLFree( pszRecord );        CPLError( CE_Failure, CPLE_AppDefined,                   <span class="stringliteral">"JDEM scanline out of order, JDEM driver does not\n"</span>                  <span class="stringliteral">"currently support partial datasets."</span> );        <span class="keywordflow">return</span> CE_Failure;    }    <span class="keywordflow">for</span>( i = 0; i &lt; nBlockXSize; i++ )        ((<span class="keywordtype">float</span> *) pImage)[i] = JDEMGetField( pszRecord + 9 + 5 * i, 5) * 0.1;    <span class="keywordflow">return</span> CE_None;}</pre></div><p>Key items to note are:<p><ul><li>It is typical to cast the GDALRasterBand::poDS member to the derived type of the owning dataset. If your RasterBand class will need privileged access to the owning dataset object, ensure it is declared as a friend (omitted above for brevity).<p></li><li>If an error occurs, report it with <a class="el" href="cpl__error_8h.html#ad2b98dd58e4de706a245faddac90403">CPLError()</a>, and return CE_Failure. Otherwise return CE_None.<p></li><li>The pImage buffer should be filled with one block of data. The block is the size declared in nBlockXSize and nBlockYSize for the raster band. The type of the data within pImage should match the type declared in eDataType in the raster band object.<p></li><li>The nBlockXOff and nBlockYOff are block offsets, so with 128x128 tiled datasets values of 1 and 1 would indicate the block going from (128,128) to (255,255) should be loaded.<p></li></ul><h2><a class="anchor" name="gdal_drivertut_driver">The Driver</a></h2>While the JDEMDataset and JDEMRasterBand are now ready to use to read image data, it still isn't clear how the GDAL system knows about the new driver. This is accomplished via the <a class="el" href="classGDALDriverManager.html">GDALDriverManager</a>. To register our format we implement a registration function:<p><div class="fragment"><pre class="fragment">CPL_C_START<span class="keywordtype">void</span>    GDALRegister_JDEM(<span class="keywordtype">void</span>);CPL_C_END...void GDALRegister_JDEM(){    <a class="code" href="classGDALDriver.html">GDALDriver</a>  *poDriver;    <span class="keywordflow">if</span>( <a class="code" href="gdal_8h.html#e8ae868eef1e4773283d137b0a1adfc4">GDALGetDriverByName</a>( <span class="stringliteral">"JDEM"</span> ) == NULL )    {        poDriver = <span class="keyword">new</span> <a class="code" href="classGDALDriver.html">GDALDriver</a>();                poDriver-&gt;<a class="code" href="classGDALMajorObject.html#f334bc8d152f130a55783ea36938735b">SetDescription</a>( <span class="stringliteral">"JDEM"</span> );        poDriver-&gt;<a class="code" href="classGDALMajorObject.html#3e157735f6ff6e11935c2a2dbcc24c92">SetMetadataItem</a>( GDAL_DMD_LONGNAME,                                    <span class="stringliteral">"Japanese DEM (.mem)"</span> );        poDriver-&gt;<a class="code" href="classGDALMajorObject.html#3e157735f6ff6e11935c2a2dbcc24c92">SetMetadataItem</a>( GDAL_DMD_HELPTOPIC,                                    <span class="stringliteral">"frmt_various.html#JDEM"</span> );        poDriver-&gt;<a class="code" href="classGDALMajorObject.html#3e157735f6ff6e11935c2a2dbcc24c92">SetMetadataItem</a>( GDAL_DMD_EXTENSION, <span class="stringliteral">"mem"</span> );        poDriver-&gt;<a class="code" href="classGDALDriver.html#31420fbca775dab837fc5c242690fbb4">pfnOpen</a> = JDEMDataset::Open;        GetGDALDriverManager()-&gt;<a class="code" href="classGDALDriverManager.html#a33cc86affa255ac37b463c129fbe49f">RegisterDriver</a>( poDriver );    }}</pre></div><p>The registration function will create an instance of a <a class="el" href="classGDALDriver.html">GDALDriver</a> object when first called, and register it with the <a class="el" href="classGDALDriverManager.html">GDALDriverManager</a>. The following fields can be set in the driver before registering it with the GDALDriverManager().<p><ul><li>The description is the short name for the format. This is a unique name for this format, often used to identity the driver in scripts and commandline programs. Normally 3-5 characters in length, and matching the prefix of the format classes. (mandatory)<p></li><li>GDAL_DMD_LONGNAME: A longer descriptive name for the file format, but still no longer than 50-60 characters. (mandatory)<p></li><li>GDAL_DMD_HELPTOPIC: The name of a help topic to display for this driver, if any. In this case JDEM format is contained within the various format web page held in gdal/html. (optional)<p></li><li>GDAL_DMD_EXTENSION: The extension used for files of this type. If more than one pick the primary extension, or none at all. (optional)<p></li><li>GDAL_DMD_MIMETYPE: The standard mime type for this file format, such as "image/png". (optional)<p></li><li>GDAL_DMD_CREATIONOPTIONLIST: There is evolving work on mechanisms to describe creation options. See the geotiff driver for an example of this. (optional)<p></li><li>GDAL_DMD_CREATIONDATATYPES: A list of space separated data types supported by this create when creating new datasets. If a Create() method exists, these will be will supported. If a CreateCopy() method exists, this will be a list of types that can be losslessly exported but it may include weaker data types than the type eventually written. For instance, a format with a CreateCopy() method, and that always writes Float32 might also list Byte, Int16, and UInt16 since they can losslessly translated to Float32. An example value might be "Byte Int16 UInt16". (required - if creation supported)<p></li><li>pfnOpen: The function to call to try opening files of this format. (optional)<p></li><li>pfnCreate: The function to call to create new updatable datasets of this format. (optional)<p></li><li>pfnCreateCopy: The function to call to create a new dataset of this format copied from another source, but not necessary updatable. (optional)<p></li><li>pfnDelete: The function to call to delete a dataset of this format. (optional)<p></li><li>pfnUnloadDriver: A function called only when the driver is destroyed. Could be used to cleanup data at the driver level. Rarely used. (optional)<p></li></ul><h2><a class="anchor" name="gdal_drivertut_addingdriver">Adding Driver to GDAL Tree</a></h2>Note that the GDALRegister_JDEM() method must be called by the higher level program in order to have access to the JDEM driver. Normal practice when writing new drivers is to:<p><ol><li>Add a driver directory under gdal/frmts, with the directory name the same as the short name.<p></li><li>Add a GNUmakefile and makefile.vc in that directory modelled on those from other similar directories (ie. the jdem directory).<p></li><li>Add the module with the dataset, and rasterband implementation. Generally this is called &lt;short_name&gt;dataset.cpp, with all the GDAL specific code in one file, though that is not required.<p></li><li>Add the registration entry point declaration (ie. GDALRegister_JDEM()) to gdal/gcore/gdal_frmts.h.<p></li><li>Add a call to the registration function to frmts/gdalallregister.c, protected by an appropriate ifdef.<p></li><li>Add the format short name to the GDAL_FORMATS macro in GDALmake.opt.in (and to GDALmake.opt).<p></li><li>Add a format specific item to the EXTRAFLAGS macro in frmts/makefile.vc. </li></ol><p>Once this is all done, it should be possible to rebuild GDAL, and have the new format available in all the utilities. The gdalinfo utility can be used to test that opening and reporting on the format is working, and the gdal_translate utility can be used to test image reading.<h2><a class="anchor" name="gdal_drivertut_georef">Adding Georeferencing</a></h2>Now we will take the example a step forward, adding georeferencing support. We add the following two virtual method overrides to JDEMDataset, taking care to exactly match the signature of the method on the GDALRasterDataset base class.<p><div class="fragment"><pre class="fragment">    CPLErr      GetGeoTransform( <span class="keywordtype">double</span> * padfTransform );    <span class="keyword">const</span> <span class="keywordtype">char</span> *GetProjectionRef();</pre></div><p>The implementation of GetGeoTransform() just copies the usual geotransform matrix into the supplied buffer. Note that GetGeoTransform() may be called a lot, so it isn't generally wise to do a lot of computation in it. In many cases the Open() will collect the geotransform, and this method will just copy it over. Also note that the geotransform return is based on an anchor point at the top left corner of the top left pixel, not the center of pixel approach used in some packages.<p><div class="fragment"><pre class="fragment">CPLErr <a class="code" href="classGDALDataset.html#f9593cc241e7d140f5f3c4798a43a668">JDEMDataset::GetGeoTransform</a>( <span class="keywordtype">double</span> * padfTransform ){    <span class="keywordtype">double</span>      dfLLLat, dfLLLong, dfURLat, dfURLong;    dfLLLat = JDEMGetAngle( (<span class="keywordtype">char</span> *) abyHeader + 29 );    dfLLLong = JDEMGetAngle( (<span class="keywordtype">char</span> *) abyHeader + 36 );    dfURLat = JDEMGetAngle( (<span class="keywordtype">char</span> *) abyHeader + 43 );    dfURLong = JDEMGetAngle( (<span class="keywordtype">char</span> *) abyHeader + 50 );        padfTransform[0] = dfLLLong;    padfTransform[3] = dfURLat;    padfTransform[1] = (dfURLong - dfLLLong) / GetRasterXSize();    padfTransform[2] = 0.0;            padfTransform[4] = 0.0;    padfTransform[5] = -1 * (dfURLat - dfLLLat) / GetRasterYSize();    <span class="keywordflow">return</span> CE_None;}</pre></div><p>The GetProjectionRef() method returns a pointer to an internal string containing a coordinate system definition in OGC WKT format. In this case the coordinate system is fixed for all files of this format, but in more complex cases a definition may need to be composed on the fly, in which case it may be helpful to use the OGRSpatialReference class to help build the definition.<p><div class="fragment"><pre class="fragment"><span class="keyword">const</span> <span class="keywordtype">char</span> *<a class="code" href="classGDALDataset.html#a42537e1062ce254d124b29ff3ebe857">JDEMDataset::GetProjectionRef</a>(){    <span class="keywordflow">return</span>( <span class="stringliteral">"GEOGCS[\"Tokyo\",DATUM[\"Tokyo\",SPHEROID[\"Bessel 1841\","</span>        <span class="stringliteral">"6377397.155,299.1528128,AUTHORITY[\"EPSG\",7004]],TOWGS84[-148,"</span>        <span class="stringliteral">"507,685,0,0,0,0],AUTHORITY[\"EPSG\",6301]],PRIMEM[\"Greenwich\","</span>        <span class="stringliteral">"0,AUTHORITY[\"EPSG\",8901]],UNIT[\"DMSH\",0.0174532925199433,"</span>        <span class="stringliteral">"AUTHORITY[\"EPSG\",9108]],AXIS[\"Lat\",NORTH],AXIS[\"Long\",EAST],"</span>        <span class="stringliteral">"AUTHORITY[\"EPSG\",4301]]"</span> );}</pre></div><p>

⌨️ 快捷键说明

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