📄 gdal_vrttut.html
字号:
</KernelFilteredSource></pre></div><p></li></ul><h2><a class="anchor" name="gdal_vrttut_vrt">.vrt Descriptions for Raw Files</a></h2>So far we have described how to derive new virtual datasets from existing files supports by GDAL. However, it is also common to need to utilize raw binary raster files for which the regular layout of the data is known but for which no format specific driver exists. This can be accomplished by writing a .vrt file describing the raw file.<p>For example, the following .vrt describes a raw raster file containing floating point complex pixels in a file called l2p3hhsso.img. The image data starts from the first byte (ImageOffset=0). The byte offset between pixels is 8 (PixelOffset=8), the size of a CFloat32. The byte offset from the start of one line to the start of the next is 9376 bytes (LineOffset=9376) which is the width (1172) times the size of a pixel (8).<p><div class="fragment"><pre class="fragment"><VRTDataset rasterXSize=<span class="stringliteral">"1172"</span> rasterYSize=<span class="stringliteral">"1864"</span>> <VRTRasterBand dataType=<span class="stringliteral">"CFloat32"</span> band=<span class="stringliteral">"1"</span> subClass=<span class="stringliteral">"VRTRawRasterBand"</span>> <SourceFilename relativetoVRT=<span class="stringliteral">"1"</span>>l2p3hhsso.img</SourceFilename> <ImageOffset>0</ImageOffset> <PixelOffset>8</PixelOffset> <LineOffset>9376</LineOffset> <ByteOrder>MSB</ByteOrder> </VRTRasterBand></VRTDataset></pre></div><p>Some things to note are that the VRTRasterBand has a subClass specifier of "VRTRawRasterBand". Also, the VRTRasterBand contains a number of previously unseen elements but no "source" information. VRTRawRasterBands may never have sources (ie. SimpleSource), but should contain the following elements in addition to all the normal "metadata" elements previously described which are still supported.<p><ul><li><b>SourceFilename</b>: The name of the raw file containing the data for this band. The relativeToVRT attribute can be used to indicate if the SourceFilename is relative to the .vrt file (1) or not (0).<p></li><li><b>ImageOffset</b>: The offset in bytes to the beginning of the first pixel of data of this image band. Defaults to zero.<p></li><li><b>PixelOffset</b>: The offset in bytes from the beginning of one pixel and the next on the same line. In packed single band data this will be the size of the <b>dataType</b> in bytes.<p></li><li><b>LineOffset</b>: The offset in bytes from the beginning of one scanline of data and the next scanline of data. In packed single band data this will be PixelOffset * rasterXSize.<p></li><li><b>ByteOrder</b>: Defines the byte order of the data on disk. Either LSB (Least Significant Byte first) such as the natural byte order on Intel x86 systems or MSB (Most Significant Byte first) such as the natural byte order on Motorola or Sparc systems. Defaults to being the local machine order.<p></li></ul><p>A few other notes:<p><ul><li>The image data on disk is assumed to be of the same data type as the band <b>dataType</b> of the VRTRawRasterBand.<p></li><li>All the non-source attributes of the VRTRasterBand are supported, including color tables, metadata, nodata values, and color interpretation.<p></li><li>The VRTRawRasterBand supports in place update of the raster, whereas the source based VRTRasterBand is always read-only.<p></li><li>The OpenEV tool includes a File menu option to input parameters describing a raw raster file in a GUI and create the corresponding .vrt file.<p></li><li>Multiple bands in the one .vrt file can come from the same raw file. Just ensure that the ImageOffset, PixelOffset, and LineOffset definition for each band is appropriate for the pixels of that particular band.<p></li></ul><p>Another example, in this case a 400x300 RGB pixel interleaved image.<p><div class="fragment"><pre class="fragment"><VRTDataset rasterXSize=<span class="stringliteral">"400"</span> rasterYSize=<span class="stringliteral">"300"</span>> <VRTRasterBand dataType=<span class="stringliteral">"Byte"</span> band=<span class="stringliteral">"1"</span> subClass=<span class="stringliteral">"VRTRawRasterBand"</span>> <ColorInterp>Red</ColorInterp> <SourceFilename relativetoVRT=<span class="stringliteral">"1"</span>>rgb.raw</SourceFilename> <ImageOffset>0</ImageOffset> <PixelOffset>3</PixelOffset> <LineOffset>1200</LineOffset> </VRTRasterBand> <VRTRasterBand dataType=<span class="stringliteral">"Byte"</span> band=<span class="stringliteral">"2"</span> subClass=<span class="stringliteral">"VRTRawRasterBand"</span>> <ColorInterp>Green</ColorInterp> <SourceFilename relativetoVRT=<span class="stringliteral">"1"</span>>rgb.raw</SourceFilename> <ImageOffset>1</ImageOffset> <PixelOffset>3</PixelOffset> <LineOffset>1200</LineOffset> </VRTRasterBand> <VRTRasterBand dataType=<span class="stringliteral">"Byte"</span> band=<span class="stringliteral">"3"</span> subClass=<span class="stringliteral">"VRTRawRasterBand"</span>> <ColorInterp>Blue</ColorInterp> <SourceFilename relativetoVRT=<span class="stringliteral">"1"</span>>rgb.raw</SourceFilename> <ImageOffset>2</ImageOffset> <PixelOffset>3</PixelOffset> <LineOffset>1200</LineOffset> </VRTRasterBand></VRTDataset></pre></div><h2><a class="anchor" name="gdal_vrttut_creation">Programatic Creation of VRT Datasets</a></h2>The VRT driver supports several methods of creating VRT datasets. As of GDAL 1.2.0 the <a class="el" href="vrtdataset_8h-source.html">vrtdataset.h</a> include file should be installed with the core GDAL include files, allowing direct access to the VRT classes. However, even without that most capabilities remain available through standard GDAL interfaces.<p>To create a VRT dataset that is a clone of an existing dataset use the CreateCopy() method. For example to clone utm.tif into a wrk.vrt file in C++ the following could be used:<p><div class="fragment"><pre class="fragment"> <a class="code" href="classGDALDriver.html">GDALDriver</a> *poDriver = (<a class="code" href="classGDALDriver.html">GDALDriver</a> *) <a class="code" href="gdal_8h.html#e8ae868eef1e4773283d137b0a1adfc4">GDALGetDriverByName</a>( <span class="stringliteral">"VRT"</span> ); <a class="code" href="classGDALDataset.html">GDALDataset</a> *poSrcDS, *poVRTDS; poSrcDS = (<a class="code" href="classGDALDataset.html">GDALDataset</a> *) <a class="code" href="gdal_8h.html#347b1025e090c5238196b658463addd3">GDALOpenShared</a>( <span class="stringliteral">"utm.tif"</span>, <a class="code" href="gdal_8h.html#045e3967c208993f70257bfd40c9f1d75a021a550b9d5640307d3c0e7e35b732">GA_ReadOnly</a> ); poVRTDS = poDriver-><a class="code" href="classGDALDriver.html#d0f7a33b0bd7f9d685bbd90d04fde629">CreateCopy</a>( <span class="stringliteral">"wrk.vrt"</span>, poSrcDS, FALSE, NULL, NULL, NULL ); <span class="keyword">delete</span> poVRTDS; <span class="keyword">delete</span> poSrcDS;</pre></div><p>To create a virtual copy of a dataset with some attributes added or changed such as metadata or coordinate system that are often hard to change on other formats, you might do the following. In this case, the virtual dataset is created "in memory" only by virtual of creating it with an empty filename, and then used as a modified source to pass to a CreateCopy() written out in TIFF format.<p><div class="fragment"><pre class="fragment"> poVRTDS = poDriver-><a class="code" href="classGDALDriver.html#d0f7a33b0bd7f9d685bbd90d04fde629">CreateCopy</a>( <span class="stringliteral">""</span>, poSrcDS, FALSE, NULL, NULL, NULL ); poVRTDS-><a class="code" href="classGDALMajorObject.html#3e157735f6ff6e11935c2a2dbcc24c92">SetMetadataItem</a>( <span class="stringliteral">"SourceAgency"</span>, <span class="stringliteral">"United States Geological Survey"</span>); poVRTDS-><a class="code" href="classGDALMajorObject.html#3e157735f6ff6e11935c2a2dbcc24c92">SetMetadataItem</a>( <span class="stringliteral">"SourceDate"</span>, <span class="stringliteral">"July 21, 2003"</span> ); poVRTDS-><a class="code" href="classGDALDataset.html#d96adcf07f2979ad176e37a7f8638fb6">GetRasterBand</a>( 1 )-><a class="code" href="classGDALRasterBand.html#c6f081d253dee55c372e54cfdd8f05a6">SetNoDataValue</a>( -999.0 ); <a class="code" href="classGDALDriver.html">GDALDriver</a> *poTIFFDriver = (<a class="code" href="classGDALDriver.html">GDALDriver</a> *) <a class="code" href="gdal_8h.html#e8ae868eef1e4773283d137b0a1adfc4">GDALGetDriverByName</a>( <span class="stringliteral">"GTiff"</span> ); <a class="code" href="classGDALDataset.html">GDALDataset</a> *poTiffDS; poTiffDS = poTIFFDriver-><a class="code" href="classGDALDriver.html#d0f7a33b0bd7f9d685bbd90d04fde629">CreateCopy</a>( <span class="stringliteral">"wrk.tif"</span>, poVRTDS, FALSE, NULL, NULL, NULL ); <span class="keyword">delete</span> poTiffDS;</pre></div><p>In this example a virtual dataset is created with the Create() method, and adding bands and sources programmatically, but still via the "generic" API. A special attribute of VRT datasets is that sources can be added to the bands by passing the XML describing the source into SetMetadata() on the special domain target "new_vrt_sources". The domain target "vrt_sources" may also be used, in which case any existing sources will be discarded before adding the new ones. In this example we construct a simple averaging filter source instead of using the simple source.<p><div class="fragment"><pre class="fragment"> <span class="comment">// construct XML for simple 3x3 average filter kernel source.</span> <span class="keyword">const</span> <span class="keywordtype">char</span> *pszFilterSourceXML =<span class="stringliteral">"<KernelFilteredSource>"</span><span class="stringliteral">" <SourceFilename>utm.tif</SourceFilename>1<SourceBand>1</SourceBand>"</span><span class="stringliteral">" <Kernel>"</span><span class="stringliteral">" <Size>3</Size>"</span><span class="stringliteral">" <Coefs>0.111 0.111 0.111 0.111 0.111 0.111 0.111 0.111 0.111</Coefs>"</span><span class="stringliteral">" </Kernel>"</span><span class="stringliteral">"</KernelFilteredSource>"</span>; <span class="comment">// Create the virtual dataset. </span> poVRTDS = poDriver-><a class="code" href="classGDALDriver.html#191dc4a5c8f48c1dea4083c711b8f7c4">Create</a>( <span class="stringliteral">""</span>, 512, 512, 1, <a class="code" href="gdal_8h.html#22e22ce0a55036a96f652765793fb7a438a66c26861d368e95ba42106ee3ab92">GDT_Byte</a>, NULL ); poVRTDS-><a class="code" href="classGDALDataset.html#d96adcf07f2979ad176e37a7f8638fb6">GetRasterBand</a>(1)-><a class="code" href="classGDALMajorObject.html#3e157735f6ff6e11935c2a2dbcc24c92">SetMetadataItem</a>(<span class="stringliteral">"source_0"</span>,pszFilterSourceXML<span class="stringliteral">",</span><span class="stringliteral"> "</span>new_vrt_sources<span class="stringliteral">");</span></pre></div><p>A more general form of this that will produce a 3x3 average filtered clone of any input datasource might look like the following. In this case we deliberately set the filtered datasource as in the "vrt_sources" domain to override the SimpleSource created by the CreateCopy() method. The fact that we used CreateCopy() ensures that all the other metadata, georeferencing and so forth is preserved from the source dataset ... the only thing we are changing is the data source for each band.<p><div class="fragment"><pre class="fragment"> <span class="keywordtype">int</span> nBand; <a class="code" href="classGDALDriver.html">GDALDriver</a> *poDriver = (<a class="code" href="classGDALDriver.html">GDALDriver</a> *) <a class="code" href="gdal_8h.html#e8ae868eef1e4773283d137b0a1adfc4">GDALGetDriverByName</a>( <span class="stringliteral">"VRT"</span> ); <a class="code" href="classGDALDataset.html">GDALDataset</a> *poSrcDS, *poVRTDS; poSrcDS = (<a class="code" href="classGDALDataset.html">GDALDataset</a> *) <a class="code" href="gdal_8h.html#347b1025e090c5238196b658463addd3">GDALOpenShared</a>( pszSourceFilename, <a class="code" href="gdal_8h.html#045e3967c208993f70257bfd40c9f1d75a021a550b9d5640307d3c0e7e35b732">GA_ReadOnly</a> ); poVRTDS = poDriver-><a class="code" href="classGDALDriver.html#d0f7a33b0bd7f9d685bbd90d04fde629">CreateCopy</a>( <span class="stringliteral">""</span>, poSrcDS, FALSE, NULL, NULL, NULL ); <span class="keywordflow">for</span>( nBand = 1; nBand <= poVRTDS-><a class="code" href="classGDALDataset.html#01ed7cc3d711651470212dac01af69a0">GetRasterCount</a>(); nBand++ ) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -