1.. _raster.vrt:
2
3================================================================================
4VRT -- GDAL Virtual Format
5================================================================================
6
7.. shortname:: VRT
8
9.. built_in_by_default::
10
11Introduction
12------------
13
14The VRT driver is a format driver for GDAL that allows a virtual GDAL dataset
15to be composed from other GDAL datasets with repositioning, and algorithms
16potentially applied as well as various kinds of metadata altered or added.
17VRT descriptions of datasets can be saved in an XML format normally given the
18extension .vrt.
19
20The VRT format can also describe :ref:`gdal_vrttut_warped`
21and :ref:`gdal_vrttut_pansharpen`
22
23An example of a simple .vrt file referring to a 512x512 dataset with one band
24loaded from utm.tif might look like this:
25
26.. code-block:: xml
27
28    <VRTDataset rasterXSize="512" rasterYSize="512">
29        <GeoTransform>440720.0, 60.0, 0.0, 3751320.0, 0.0, -60.0</GeoTransform>
30        <VRTRasterBand dataType="Byte" band="1">
31            <ColorInterp>Gray</ColorInterp>
32            <SimpleSource>
33            <SourceFilename relativeToVRT="1">utm.tif</SourceFilename>
34            <SourceBand>1</SourceBand>
35            <SrcRect xOff="0" yOff="0" xSize="512" ySize="512"/>
36            <DstRect xOff="0" yOff="0" xSize="512" ySize="512"/>
37            </SimpleSource>
38        </VRTRasterBand>
39    </VRTDataset>
40
41Many aspects of the VRT file are a direct XML encoding of the
42:ref:`raster_data_model` which should be reviewed
43for understanding of the semantics of various elements.
44
45VRT files can be produced by translating to VRT format.  The resulting file can
46then be edited to modify mappings, add metadata or other purposes.  VRT files
47can also be produced programmatically by various means.
48
49This tutorial will cover the .vrt file format (suitable for users editing
50.vrt files), and how .vrt files may be created and manipulated programmatically
51for developers.
52
53.vrt Format
54-----------
55
56A `XML schema of the GDAL VRT format <https://raw.githubusercontent.com/OSGeo/gdal/master/gdal/data/gdalvrt.xsd>`_
57is available.
58
59Virtual files stored on disk are kept in an XML format with the following
60elements.
61
62**VRTDataset**: This is the root element for the whole GDAL dataset. It must have the attributes rasterXSize and rasterYSize describing the width and height of the dataset in pixels. It may have a subClass attributes with values VRTWarpedDataset (:ref:`gdal_vrttut_warped`) or VRTPansharpenedDataset (:ref:`gdal_vrttut_pansharpen`). It may have SRS, GeoTransform, GCPList, Metadata, MaskBand and VRTRasterBand subelements.
63
64.. code-block:: xml
65
66    <VRTDataset rasterXSize="512" rasterYSize="512">
67
68VRTDataset
69++++++++++
70
71The allowed subelements for VRTDataset are :
72
73- **SRS**: This element contains the spatial reference system (coordinate system) in OGC WKT format.  Note that this must be appropriately escaped for XML, so items like quotes will have the ampersand escape sequences substituted. As as well WKT, and valid input to the SetFromUserInput() method (such as well known GEOGCS names, and PROJ.4 format) is also allowed in the SRS element.
74
75.. code-block:: xml
76
77  <SRS dataAxisToSRSAxisMapping="1,2">PROJCS[&quot;NAD27 / UTM zone 11N&quot;,GEOGCS[&quot;NAD27&quot;,DATUM[&quot;North_American_Datum_1927&quot;,SPHEROID[&quot;Clarke 1866&quot;,6378206.4,294.9786982139006,AUTHORITY[&quot;EPSG&quot;,&quot;7008&quot;]],AUTHORITY[&quot;EPSG&quot;,&quot;6267&quot;]],PRIMEM[&quot;Greenwich&quot;,0],UNIT[&quot;degree&quot;,0.0174532925199433],AUTHORITY[&quot;EPSG&quot;,&quot;4267&quot;]],PROJECTION[&quot;Transverse_Mercator&quot;],PARAMETER[&quot;latitude_of_origin&quot;,0],PARAMETER[&quot;central_meridian&quot;,-117],PARAMETER[&quot;scale_factor&quot;,0.9996],PARAMETER[&quot;false_easting&quot;,500000],PARAMETER[&quot;false_northing&quot;,0],UNIT[&quot;metre&quot;,1,AUTHORITY[&quot;EPSG&quot;,&quot;9001&quot;]],AUTHORITY[&quot;EPSG&quot;,&quot;26711&quot;]]</SRS>
78
79The **dataAxisToSRSAxisMapping** attribute is allowed since GDAL 3.0 to describe the relationship between the axis indicated in the CRS definition and the axis of the GeoTransform or GCP metadata. The value of the attribute is a comma separated list of integers. The number of elements of this list must be the number of axis of the CRS. Values start at 1. If m denotes the array values of this attribute, then m[0] is the data axis number for the first axis of the CRS. If the attribute is missing, then the OAMS_TRADITIONAL_GIS_ORDER data axis to CRS axis mapping strategy is implied.
80
81- **GeoTransform**: This element contains a six value affine geotransformation for the dataset, mapping between pixel/line coordinates and georeferenced coordinates.
82
83.. code-block:: xml
84
85  <GeoTransform>440720.0,  60,  0.0,  3751320.0,  0.0, -60.0</GeoTransform>
86
87- **GCPList**: This element contains a list of Ground Control Points for the dataset, mapping between pixel/line coordinates and georeferenced coordinates. The Projection attribute should contain the SRS of the georeferenced coordinates in the same format as the SRS element. The dataAxisToSRSAxisMapping attribute is the same as in the SRS element.
88
89.. code-block:: xml
90
91    <GCPList Projection="EPSG:4326">
92        <GCP Id="1" Info="a" Pixel="0.5" Line="0.5" X="0.0" Y="0.0" Z="0.0" />
93        <GCP Id="2" Info="b" Pixel="13.5" Line="23.5" X="1.0" Y="2.0" Z="0.0" />
94    </GCPList>
95
96- **Metadata**: This element contains a list of metadata name/value pairs associated with the VRTDataset as a whole, or a VRTRasterBand. It has <MDI> (metadata item) subelements which have a "key" attribute and the value as the data of the element. The Metadata element can be repeated multiple times, in which case it must be accompanied with a "domain" attribute to indicate the name of the metadata domain.
97
98.. code-block:: xml
99
100  <Metadata>
101    <MDI key="md_key">Metadata value</MDI>
102  </Metadata>
103
104- **MaskBand**: This element represents a mask band that is shared between all bands on the dataset (see GMF_PER_DATASET in RFC 15). It must contain a single VRTRasterBand child element, that is the description of the mask band itself.
105
106.. code-block:: xml
107
108  <MaskBand>
109    <VRTRasterBand dataType="Byte">
110      <SimpleSource>
111        <SourceFilename relativeToVRT="1">utm.tif</SourceFilename>
112        <SourceBand>mask,1</SourceBand>
113        <SrcRect xOff="0" yOff="0" xSize="512" ySize="512"/>
114        <DstRect xOff="0" yOff="0" xSize="512" ySize="512"/>
115      </SimpleSource>
116    </VRTRasterBand>
117  </MaskBand>
118
119- **OverviewList**: (GDAL >= 3.2.0, not valid for VRTPansharpenedDataset)
120  This elements contains a list of overview factors, separated by space, to
121  create "virtual overviews". For example ``2 4``. It can be used so that bands
122  of the VRT datasets declare overviews. This only makes sense to use if the
123  sources added in those bands have themselves overviews compatible of the
124  declared factor. It is generally not needed to use this mechanism, since
125  downsampling pixel requests on a VRT dataset/band are able to use  of the
126  sources, even when the VRT bands do not declare them. One situation where
127  explicit overviews are needed at the VRT level is for example warping a VRT
128  to a lower resolution.
129  This element can also be used to an existing VRT dataset by running
130  :cpp:func:`GDALDataset::BuildOverviews` or :program:`gdaladdo` with the
131  :decl_configoption:`VRT_VIRTUAL_OVERVIEWS` configuration option set to ``YES``.
132  Virtual overviews have the least priority compared to the **Overview** element
133  at the **VRTRasterBand** level, or to materialized .vrt.ovr files.
134
135
136- **VRTRasterBand**: This represents one band of a dataset.
137
138VRTRasterBand
139+++++++++++++
140
141The attributes for VRTRasterBand are:
142
143- **dataType** (optional): type of the pixel data associated with this band (use
144  names Byte, UInt16, Int16, UInt32, Int32, Float32, Float64, CInt16, CInt32, CFloat32 or CFloat64).
145  If not specified, defaults to 1
146
147- **band** (optional): band number this element represents (1 based).
148
149- **blockXSize** (optional, GDAL >= 3.3): block width.
150  If not specified, defaults to the minimum of the raster width and 128.
151
152- **blockYSize** (optional, GDAL >= 3.3): block height.
153  If not specified, defaults to the minimum of the raster height and 128.
154
155This element may have Metadata, ColorInterp, NoDataValue, HideNoDataValue, ColorTable, GDALRasterAttributeTable, Description and MaskBand subelements as well as the various kinds of source elements such as SimpleSource, ComplexSource, etc.  A raster band may have many "sources" indicating where the actual raster data should be fetched from, and how it should be mapped into the raster bands pixel space.
156
157The allowed subelements for VRTRasterBand are :
158
159- **ColorInterp**: The data of this element should be the name of a color interpretation type.  One of Gray, Palette, Red, Green, Blue, Alpha, Hue, Saturation, Lightness, Cyan, Magenta, Yellow, Black, or Unknown.
160
161.. code-block:: xml
162
163  <ColorInterp>Gray</ColorInterp>:
164
165- **NoDataValue**: If this element exists a raster band has a nodata value associated with, of the value given as data in the element. This must not be confused with the NODATA element of a VRTComplexSource element.
166
167.. code-block:: xml
168
169  <NoDataValue>-100.0</NoDataValue>
170
171- **HideNoDataValue**: If this value is 1, the nodata value will not be reported.  Essentially, the caller will not be aware of a nodata pixel when it reads one.  Any datasets copied/translated from this will not have a nodata value.  This is useful when you want to specify a fixed background value for the dataset.  The background will be the value specified by the NoDataValue element. Default value is 0 when this element is absent.
172
173.. code-block:: xml
174
175  <HideNoDataValue>1</HideNoDataValue>
176
177- **ColorTable**: This element is parent to a set of Entry elements defining the entries in a color table.  Currently only RGBA color tables are supported with c1 being red, c2 being green, c3 being blue and c4 being alpha.  The entries are ordered and will be assumed to start from color table entry 0.
178
179.. code-block:: xml
180
181    <ColorTable>
182      <Entry c1="0" c2="0" c3="0" c4="255"/>
183      <Entry c1="145" c2="78" c3="224" c4="255"/>
184    </ColorTable>
185
186- **GDALRasterAttributeTable**: (GDAL >=2.3) This element is parent to a set of FieldDefn elements defining the columns of a raster attribute table, followed by a set of Row element defining the values of the columns of each row.
187
188.. code-block:: xml
189
190    <GDALRasterAttributeTable>
191      <FieldDefn index="0">
192        <Name>Value</Name>
193        <Type>0</Type>
194        <Usage>0</Usage>
195      </FieldDefn>
196      <FieldDefn index="1">
197        <Name>Red</Name>
198        <Type>0</Type>
199        <Usage>6</Usage>
200      </FieldDefn>
201      <FieldDefn index="2">
202        <Name>Green</Name>
203        <Type>0</Type>
204        <Usage>7</Usage>
205      </FieldDefn>
206      <FieldDefn index="3">
207        <Name>Blue</Name>
208        <Type>0</Type>
209        <Usage>8</Usage>
210      </FieldDefn>
211      <Row index="0">
212        <F>-500</F>
213        <F>127</F>
214        <F>40</F>
215        <F>65</F>
216      </Row>
217      <Row index="1">
218        <F>-400</F>
219        <F>154</F>
220        <F>168</F>
221        <F>118</F>
222      </Row>
223    </GDALRasterAttributeTable>
224
225- **Description**: This element contains the optional description of a raster band as its text value.
226
227.. code-block:: xml
228
229  <Description>Crop Classification Layer</Description>
230
231- **UnitType**: This optional element contains the vertical units for elevation band data.  One of "m" for meters or "ft" for feet. Default assumption is meters.
232
233.. code-block:: xml
234
235  <UnitType>ft</UnitType>
236
237- **Offset**: This optional element contains the offset that should be applied when computing "real" pixel values from scaled pixel values on a raster band.   The default is 0.0.
238
239.. code-block:: xml
240
241  <Offset>0.0</Offset>
242
243- **Scale**: This optional element contains the scale that should be applied when computing "real" pixel values from scaled pixel values on a raster band.   The default is 1.0.
244
245.. code-block:: xml
246
247  <Scale>0.0</Scale>
248
249- **Overview**: This optional element describes one overview level for the band.  It should have a child SourceFilename and SourceBand element.  The SourceFilename may have a relativeToVRT boolean attribute.  Multiple elements may be used to describe multiple overviews.
250
251.. code-block:: xml
252
253    <Overview>
254      <SourceFilename relativeToVRT="1">yellowstone_2.1.ntf.r2</SourceFilename>
255      <SourceBand>1</SourceBand>
256    </Overview>
257
258- **CategoryNames**: This optional element contains a list of Category subelements with the names of the categories for classified raster band.
259
260.. code-block:: xml
261
262  <CategoryNames>
263    <Category>Missing</Category>
264    <Category>Non-Crop</Category>
265    <Category>Wheat</Category>
266    <Category>Corn</Category>
267    <Category>Soybeans</Category>
268  </CategoryNames>
269
270- **SimpleSource**: The SimpleSource_ indicates that raster data should be read from a separate dataset, indicating the dataset, and band to be read from, and how the data should map into this bands raster space.
271
272- **AveragedSource**: The AveragedSource is derived from the SimpleSource and shares the same properties except that it uses an averaging resampling instead of a nearest neighbour algorithm as in SimpleSource, when the size of the destination rectangle is not the same as the size of the source rectangle. Note: a more general mechanism to specify resampling algorithms can be used. See above paragraph about the 'resampling' attribute.
273
274- **ComplexSource**: The ComplexSource_ is derived from the SimpleSource (so it shares the SourceFilename, SourceBand, SrcRect and DestRect elements), but it provides support to rescale and offset the range of the source values. Certain regions of the source can be masked by specifying the NODATA value, or starting with GDAL 3.3, with the <UseMaskBand>true</UseMaskBand> element.
275
276- **KernelFilteredSource**: The KernelFilteredSource_ is a pixel source derived from the Simple Source (so it shares the SourceFilename, SourceBand, SrcRect and DestRect elements, but it also passes the data through a simple filtering kernel specified with the Kernel element.
277
278- **MaskBand**: This element represents a mask band that is specific to the VRTRasterBand it contains. It must contain a single VRTRasterBand child element, that is the description of the mask band itself.
279
280Sources
281*******
282
283SimpleSource
284~~~~~~~~~~~~
285
286The SimpleSource may have the SourceFilename, SourceBand, SrcRect, and DstRect
287subelements.  The SrcRect element will indicate what rectangle on the indicated
288source file should be read, and the DstRect element indicates how that
289rectangle of source data should be mapped into the VRTRasterBands space.
290
291The relativeToVRT attribute on the SourceFilename indicates whether the
292filename should be interpreted as relative to the .vrt file (value is 1)
293or not relative to the .vrt file (value is 0).  The default is 0.
294
295Some characteristics of the source band can be specified in the optional
296SourceProperties tag to enable the VRT driver to differ the opening of the source
297dataset until it really needs to read data from it. This is particularly useful
298when building VRTs with a big number of source datasets. The needed parameters are the
299raster dimensions, the size of the blocks and the data type. If the SourceProperties
300tag is not present, the source dataset will be opened at the same time as the VRT itself.
301
302The content of the SourceBand subelement can refer to
303a mask band. For example mask,1 means the mask band of the first band of the source.
304
305.. code-block:: xml
306
307    <SimpleSource>
308      <SourceFilename relativeToVRT="1">utm.tif</SourceFilename>
309      <SourceBand>1</SourceBand>
310      <SourceProperties RasterXSize="512" RasterYSize="512" DataType="Byte" BlockXSize="128" BlockYSize="128"/>
311      <SrcRect xOff="0" yOff="0" xSize="512" ySize="512"/>
312      <DstRect xOff="0" yOff="0" xSize="512" ySize="512"/>
313    </SimpleSource>
314
315A OpenOptions subelement can be added to specify
316the open options to apply when opening the source dataset. It has <OOI> (open option item)
317subelements which have a "key" attribute and the value as the data of the element.
318
319.. code-block:: xml
320
321    <SimpleSource>
322      <SourceFilename relativeToVRT="1">utm.tif</SourceFilename>
323      <OpenOptions>
324          <OOI key="OVERVIEW_LEVEL">0</OOI>
325      </OpenOptions>
326      <SourceBand>1</SourceBand>
327      <SourceProperties RasterXSize="256" RasterYSize="256" DataType="Byte" BlockXSize="128" BlockYSize="128"/>
328      <SrcRect xOff="0" yOff="0" xSize="256" ySize="256"/>
329      <DstRect xOff="0" yOff="0" xSize="256" ySize="256"/>
330    </SimpleSource>
331
332A resampling attribute can be specified on a SimpleSource
333or ComplexSource element to specified the resampling algorithm used when the
334size of the destination rectangle is not the same as the size of the source
335rectangle. The values allowed for that attribute are : nearest,bilinear,cubic,
336cubicspline,lanczos,average,mode.
337
338.. code-block:: xml
339
340    <SimpleSource resampling="cubic">
341      <SourceFilename relativeToVRT="1">utm.tif</SourceFilename>
342      <SourceBand>1</SourceBand>
343      <SourceProperties RasterXSize="256" RasterYSize="256" DataType="Byte" BlockXSize="128" BlockYSize="128"/>
344      <SrcRect xOff="0" yOff="0" xSize="256" ySize="256"/>
345      <DstRect xOff="0" yOff="0" xSize="128" ySize="128"/>
346    </SimpleSource>
347
348ComplexSource
349~~~~~~~~~~~~~
350
351Alternatively to linear scaling, non-linear
352scaling using a power function can be used by specifying the Exponent,
353SrcMin, SrcMax, DstMin and DstMax elements. If SrcMin and SrcMax are
354not specified, they are computed from the source minimum and maximum
355value (which might require analyzing the whole source dataset). Exponent
356must be positive. (Those 5 values can be set with the -exponent and -scale
357options of gdal_translate.)
358
359The ComplexSource supports adding a custom lookup table to transform
360the source values to the destination. The LUT can be specified using
361the following form:
362
363.. code-block:: xml
364
365    <LUT>[src value 1]:[dest value 1],[src value 2]:[dest value 2],...</LUT>
366
367The intermediary values are calculated using a linear interpolation
368between the bounding destination values of the corresponding range.
369
370The ComplexSource supports fetching a color component from a source raster
371band that has a color table. The ColorTableComponent value is the index of the
372color component to extract : 1 for the red band, 2 for the green band, 3 for
373the blue band or 4 for the alpha band.
374
375When transforming the source values the operations are executed
376in the following order:
377
378- Masking, if the NODATA element is set or, starting with GDAL 3.3,
379  if the UseMaskBand is set to true and the source band has a mask band.
380  Note that this is binary masking only, so no alpha blending is done if the
381  mask band is actually an alpha band with non-0 or non-255 values.
382- Color table expansion
383- For linear scaling, applying the scale ratio, then scale offset
384- For non-linear scaling, apply (DstMax-DstMin) * pow( (SrcValue-SrcMin) / (SrcMax-SrcMin), Exponent) + DstMin
385- Table lookup
386
387.. code-block:: xml
388
389    <ComplexSource>
390      <SourceFilename relativeToVRT="1">utm.tif</SourceFilename>
391      <SourceBand>1</SourceBand>
392      <ScaleOffset>0</ScaleOffset>
393      <ScaleRatio>1</ScaleRatio>
394      <ColorTableComponent>1</ColorTableComponent>
395      <LUT>0:0,2345.12:64,56789.5:128,2364753.02:255</LUT>
396      <NODATA>0</NODATA>  <!-- if the mask is a mask or alpha band, use <UseMaskBand>true</UseMaskBand> -->
397      <SrcRect xOff="0" yOff="0" xSize="512" ySize="512"/>
398      <DstRect xOff="0" yOff="0" xSize="512" ySize="512"/>
399    </ComplexSource>
400
401Non-linear scaling:
402
403.. code-block:: xml
404
405    <ComplexSource>
406      <SourceFilename relativeToVRT="1">16bit.tif</SourceFilename>
407      <SourceBand>1</SourceBand>
408      <Exponent>0.75</Exponent>
409      <SrcMin>0</SrcMin>
410      <SrcMax>65535</SrcMax>
411      <DstMin>0</DstMin>
412      <DstMax>255</DstMax>
413      <SrcRect xOff="0" yOff="0" xSize="512" ySize="512"/>
414      <DstRect xOff="0" yOff="0" xSize="512" ySize="512"/>
415    </ComplexSource>
416
417
418KernelFilteredSource
419~~~~~~~~~~~~~~~~~~~~
420
421The Kernel element should have
422two child elements, Size and Coefs and optionally the boolean attribute
423normalized (defaults to false=0).  The size must always be an odd number,
424and the Coefs must have Size * Size entries separated by spaces.  For now
425kernel is not applied to sub-sampled or over-sampled data.
426
427.. code-block:: xml
428
429    <KernelFilteredSource>
430      <SourceFilename>/debian/home/warmerda/openev/utm.tif</SourceFilename>
431      <SourceBand>1</SourceBand>
432      <Kernel normalized="1">
433        <Size>3</Size>
434        <Coefs>0.11111111 0.11111111 0.11111111 0.11111111 0.11111111 0.11111111 0.11111111 0.11111111 0.11111111</Coefs>
435      </Kernel>
436    </KernelFilteredSource>
437
438Starting with GDAL 2.3, a separable kernel may also be used.  In this case the
439number of Coefs entries should correspond to the Size.  The Coefs specify a
440one-dimensional kernel which is applied along each axis in succession, resulting
441in far quicker execution. Many common image-processing filters are separable.
442For example, a Gaussian blur:
443
444.. code-block:: xml
445
446    <KernelFilteredSource>
447      <SourceFilename>/debian/home/warmerda/openev/utm.tif</SourceFilename>
448      <SourceBand>1</SourceBand>
449      <Kernel normalized="1">
450        <Size>13</Size>
451        <Coefs>0.01111 0.04394 0.13534 0.32465 0.60653 0.8825 1.0 0.8825 0.60653 0.32465 0.13534 0.04394 0.01111</Coefs>
452      </Kernel>
453    </KernelFilteredSource>
454
455Overviews
456---------
457
458GDAL can make efficient use of overviews available in the sources that compose
459the bands when dealing with RasterIO() requests that involve downsampling.
460But in the general case, the VRT bands themselves will not expose overviews.
461
462Except if (from top priority to lesser priority) :
463
464- The **Overview** element is present in the VRTRasterBand element. See above.
465- or external .vrt.ovr overviews are built
466- (starting with GDAL 3.2) explicit virtual overviews, if a **OverviewList** element
467  is declared in the VRTDataset element (see above).
468  Those virtual overviews will be hidden by external .vrt.ovr overviews that might be built later.
469- (starting with GDAL 2.1) implicit virtual overviews, if the VRTRasterBand are made of
470  a single SimpleSource or ComplexSource that has overviews.
471  Those virtual overviews will be hidden by external .vrt.ovr overviews that might be built later.
472
473.vrt Descriptions for Raw Files
474-------------------------------
475
476So far we have described how to derive new virtual datasets from existing
477files supports by GDAL.  However, it is also common to need to utilize
478raw binary raster files for which the regular layout of the data is known
479but for which no format specific driver exists.  This can be accomplished
480by writing a .vrt file describing the raw file.
481
482For example, the following .vrt describes a raw raster file containing
483floating point complex pixels in a file called <i>l2p3hhsso.img</i>.  The
484image data starts from the first byte (ImageOffset=0).  The byte offset
485between pixels is 8 (PixelOffset=8), the size of a CFloat32.  The byte offset
486from the start of one line to the start of the next is 9376 bytes
487(LineOffset=9376) which is the width (1172) times the size of a pixel (8).
488
489.. code-block:: xml
490
491    <VRTDataset rasterXSize="1172" rasterYSize="1864">
492        <VRTRasterBand dataType="CFloat32" band="1" subClass="VRTRawRasterBand">
493            <SourceFilename relativetoVRT="1">l2p3hhsso.img</SourceFilename>
494            <ImageOffset>0</ImageOffset>
495            <PixelOffset>8</PixelOffset>
496            <LineOffset>9376</LineOffset>
497            <ByteOrder>MSB</ByteOrder>
498        </VRTRasterBand>
499    </VRTDataset>
500
501Some things to note are that the VRTRasterBand has a subClass specifier
502of "VRTRawRasterBand".  Also, the VRTRawRasterBand contains a number of
503previously unseen elements but no "source" information.  VRTRawRasterBands
504may never have sources (i.e. SimpleSource), but should contain the following
505elements in addition to all the normal "metadata" elements previously
506described which are still supported.
507
508- **SourceFilename**: 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).
509
510- **ImageOffset**: The offset in bytes to the beginning of the first pixel of data of this image band.   Defaults to zero.
511
512- **PixelOffset**: 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 **dataType** in bytes.
513
514- **LineOffset**: 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.
515
516- **ByteOrder**: 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.
517
518A few other notes:
519
520- The image data on disk is assumed to be of the same data type as the band **dataType** of the VRTRawRasterBand.
521
522- All the non-source attributes of the VRTRasterBand are supported, including color tables, metadata, nodata values, and color interpretation.
523
524- The VRTRawRasterBand supports in place update of the raster, whereas the source based VRTRasterBand is always read-only.
525
526- 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.
527
528- 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.
529
530Another example, in this case a 400x300 RGB pixel interleaved image.
531
532.. code-block:: xml
533
534    <VRTDataset rasterXSize="400" rasterYSize="300">
535    <VRTRasterBand dataType="Byte" band="1" subClass="VRTRawRasterBand">
536        <ColorInterp>Red</ColorInterp>
537        <SourceFilename relativetoVRT="1">rgb.raw</SourceFilename>
538        <ImageOffset>0</ImageOffset>
539        <PixelOffset>3</PixelOffset>
540        <LineOffset>1200</LineOffset>
541    </VRTRasterBand>
542    <VRTRasterBand dataType="Byte" band="2" subClass="VRTRawRasterBand">
543        <ColorInterp>Green</ColorInterp>
544        <SourceFilename relativetoVRT="1">rgb.raw</SourceFilename>
545        <ImageOffset>1</ImageOffset>
546        <PixelOffset>3</PixelOffset>
547        <LineOffset>1200</LineOffset>
548    </VRTRasterBand>
549    <VRTRasterBand dataType="Byte" band="3" subClass="VRTRawRasterBand">
550        <ColorInterp>Blue</ColorInterp>
551        <SourceFilename relativetoVRT="1">rgb.raw</SourceFilename>
552        <ImageOffset>2</ImageOffset>
553        <PixelOffset>3</PixelOffset>
554        <LineOffset>1200</LineOffset>
555    </VRTRasterBand>
556    </VRTDataset>
557
558Creation of VRT Datasets
559------------------------
560
561The VRT driver supports several methods of creating VRT datasets.
562The vrtdataset.h include file should be installed with the core
563GDAL include files, allowing direct access to the VRT classes.  However,
564even without that most capabilities remain available through standard GDAL
565interfaces.
566
567To create a VRT dataset that is a clone of an existing dataset use the
568CreateCopy() method.  For example to clone utm.tif into a wrk.vrt file in
569C++ the following could be used:
570
571.. code-block:: cpp
572
573  GDALDriver *poDriver = (GDALDriver *) GDALGetDriverByName( "VRT" );
574  GDALDataset *poSrcDS, *poVRTDS;
575
576  poSrcDS = (GDALDataset *) GDALOpenShared( "utm.tif", GA_ReadOnly );
577
578  poVRTDS = poDriver->CreateCopy( "wrk.vrt", poSrcDS, FALSE, NULL, NULL, NULL );
579
580  GDALClose((GDALDatasetH) poVRTDS);
581  GDALClose((GDALDatasetH) poSrcDS);
582
583Note the use of GDALOpenShared() when opening the source dataset. It is advised
584to use GDALOpenShared() in this situation so that you are able to release
585the explicit reference to it before closing the VRT dataset itself. In other
586words, in the previous example, you could also invert the 2 last lines, whereas
587if you open the source dataset with GDALOpen(), you'd need to close the VRT dataset
588before closing the source dataset.
589
590To create a virtual copy of a dataset with some attributes added or changed
591such as metadata or coordinate system that are often hard to change on other
592formats, you might do the following.  In this case, the virtual dataset is
593created "in memory" only by virtual of creating it with an empty filename, and
594then used as a modified source to pass to a CreateCopy() written out in TIFF
595format.
596
597.. code-block:: cpp
598
599  poVRTDS = poDriver->CreateCopy( "", poSrcDS, FALSE, NULL, NULL, NULL );
600
601  poVRTDS->SetMetadataItem( "SourceAgency", "United States Geological Survey");
602  poVRTDS->SetMetadataItem( "SourceDate", "July 21, 2003" );
603
604  poVRTDS->GetRasterBand( 1 )->SetNoDataValue( -999.0 );
605
606  GDALDriver *poTIFFDriver = (GDALDriver *) GDALGetDriverByName( "GTiff" );
607  GDALDataset *poTiffDS;
608
609  poTiffDS = poTIFFDriver->CreateCopy( "wrk.tif", poVRTDS, FALSE, NULL, NULL, NULL );
610
611  GDALClose((GDALDatasetH) poTiffDS);
612
613In the above example the nodata value is set as -999. You can set the
614HideNoDataValue element in the VRT dataset's band using SetMetadataItem() on
615that band.
616
617.. code-block:: cpp
618
619  poVRTDS->GetRasterBand( 1 )->SetMetadataItem( "HideNoDataValue" , "1" );
620
621In this example a virtual dataset is created with the Create() method, and
622adding bands and sources programmatically, but still via the "generic" API.
623A special attribute of VRT datasets is that sources can be added to the VRTRasterBand
624(but not to VRTRawRasterBand) by passing the XML describing the source into SetMetadata() on the special
625domain target "new_vrt_sources".  The domain target "vrt_sources" may also be
626used, in which case any existing sources will be discarded before adding the
627new ones.  In this example we construct a simple averaging filter source
628instead of using the simple source.
629
630.. code-block:: cpp
631
632    // construct XML for simple 3x3 average filter kernel source.
633    const char *pszFilterSourceXML  =
634    "<KernelFilteredSource>"
635    "  <SourceFilename>utm.tif</SourceFilename><SourceBand>1</SourceBand>"
636    "  <Kernel>"
637    "    <Size>3</Size>"
638    "    <Coefs>0.111 0.111 0.111 0.111 0.111 0.111 0.111 0.111 0.111</Coefs>"
639    "  </Kernel>"
640    "</KernelFilteredSource>";
641
642    // Create the virtual dataset.
643    poVRTDS = poDriver->Create( "", 512, 512, 1, GDT_Byte, NULL );
644    poVRTDS->GetRasterBand(1)->SetMetadataItem("source_0",pszFilterSourceXML,
645                                                "new_vrt_sources");
646
647A more general form of this that will produce a 3x3 average filtered clone
648of any input datasource might look like the following.  In this case we
649deliberately set the filtered datasource as in the "vrt_sources" domain
650to override the SimpleSource created by the CreateCopy() method.  The fact
651that we used CreateCopy() ensures that all the other metadata, georeferencing
652and so forth is preserved from the source dataset ... the only thing we are
653changing is the data source for each band.
654
655.. code-block:: cpp
656
657    int   nBand;
658    GDALDriver *poDriver = (GDALDriver *) GDALGetDriverByName( "VRT" );
659    GDALDataset *poSrcDS, *poVRTDS;
660
661    poSrcDS = (GDALDataset *) GDALOpenShared( pszSourceFilename, GA_ReadOnly );
662
663    poVRTDS = poDriver->CreateCopy( "", poSrcDS, FALSE, NULL, NULL, NULL );
664
665    for( nBand = 1; nBand <= poVRTDS->GetRasterCount(); nBand++ )
666    {
667        char szFilterSourceXML[10000];
668
669        GDALRasterBand *poBand = poVRTDS->GetRasterBand( nBand );
670
671        sprintf( szFilterSourceXML,
672            "<KernelFilteredSource>"
673            "  <SourceFilename>%s</SourceFilename><SourceBand>%d</SourceBand>"
674            "  <Kernel>"
675            "    <Size>3</Size>"
676            "    <Coefs>0.111 0.111 0.111 0.111 0.111 0.111 0.111 0.111 0.111</Coefs>"
677            "  </Kernel>"
678            "</KernelFilteredSource>",
679            pszSourceFilename, nBand );
680
681        poBand->SetMetadataItem( "source_0", szFilterSourceXML, "vrt_sources" );
682    }
683
684The VRTDataset class is one of the few dataset implementations that supports the AddBand()
685method. The options passed to the AddBand() method can be used to control the type of the
686band created (VRTRasterBand, VRTRawRasterBand, VRTDerivedRasterBand), and in the case of
687the VRTRawRasterBand to set its various parameters. For standard VRTRasterBand, sources
688should be specified with the above SetMetadata() / SetMetadataItem() examples.
689
690.. code-block:: cpp
691
692  GDALDriver *poDriver = (GDALDriver *) GDALGetDriverByName( "VRT" );
693  GDALDataset *poVRTDS;
694
695  poVRTDS = poDriver->Create( "out.vrt", 512, 512, 0, GDT_Byte, NULL );
696  char** papszOptions = NULL;
697  papszOptions = CSLAddNameValue(papszOptions, "subclass", "VRTRawRasterBand"); // if not specified, default to VRTRasterBand
698  papszOptions = CSLAddNameValue(papszOptions, "SourceFilename", "src.tif"); // mandatory
699  papszOptions = CSLAddNameValue(papszOptions, "ImageOffset", "156"); // optional. default = 0
700  papszOptions = CSLAddNameValue(papszOptions, "PixelOffset", "2"); // optional. default = size of band type
701  papszOptions = CSLAddNameValue(papszOptions, "LineOffset", "1024"); // optional. default = size of band type * width
702  papszOptions = CSLAddNameValue(papszOptions, "ByteOrder", "LSB"); // optional. default = machine order
703  papszOptions = CSLAddNameValue(papszOptions, "relativeToVRT", "true"); // optional. default = false
704  poVRTDS->AddBand(GDT_Byte, papszOptions);
705  CSLDestroy(papszOptions);
706
707  delete poVRTDS;
708
709.. _vrt_derived_bands:
710
711Using Derived Bands (with pixel functions in C/C++)
712---------------------------------------------------
713
714A specialized type of band is a 'derived' band which derives its pixel
715information from its source bands.  With this type of band you must also
716specify a pixel function, which has the responsibility of generating the
717output raster.  Pixel functions are created by an application and then
718registered with GDAL using a unique key.
719
720Using derived bands you can create VRT datasets that manipulate bands on
721the fly without having to create new band files on disk.  For example, you
722might want to generate a band using four source bands from a nine band input
723dataset (x0, x3, x4, and x8):
724
725.. code-block:: c
726
727  band_value = sqrt((x3*x3+x4*x4)/(x0*x8));
728
729You could write the pixel function to compute this value and then register
730it with GDAL with the name "MyFirstFunction".  Then, the following VRT XML
731could be used to display this derived band:
732
733
734.. code-block:: xml
735
736    <VRTDataset rasterXSize="1000" rasterYSize="1000">
737        <VRTRasterBand dataType="Float32" band="1" subClass="VRTDerivedRasterBand">
738            <Description>Magnitude</Description>
739            <PixelFunctionType>MyFirstFunction</PixelFunctionType>
740            <SimpleSource>
741                <SourceFilename relativeToVRT="1">nine_band.dat</SourceFilename>
742                <SourceBand>1</SourceBand>
743                <SrcRect xOff="0" yOff="0" xSize="1000" ySize="1000"/>
744                <DstRect xOff="0" yOff="0" xSize="1000" ySize="1000"/>
745            </SimpleSource>
746            <SimpleSource>
747                <SourceFilename relativeToVRT="1">nine_band.dat</SourceFilename>
748                <SourceBand>4</SourceBand>
749                <SrcRect xOff="0" yOff="0" xSize="1000" ySize="1000"/>
750                <DstRect xOff="0" yOff="0" xSize="1000" ySize="1000"/>
751            </SimpleSource>
752            <SimpleSource>
753                <SourceFilename relativeToVRT="1">nine_band.dat</SourceFilename>
754                <SourceBand>5</SourceBand>
755                <SrcRect xOff="0" yOff="0" xSize="1000" ySize="1000"/>
756                <DstRect xOff="0" yOff="0" xSize="1000" ySize="1000"/>
757            </SimpleSource>
758            <SimpleSource>
759                <SourceFilename relativeToVRT="1">nine_band.dat</SourceFilename>
760                <SourceBand>9</SourceBand>
761                <SrcRect xOff="0" yOff="0" xSize="1000" ySize="1000"/>
762                <DstRect xOff="0" yOff="0" xSize="1000" ySize="1000"/>
763            </SimpleSource>
764        </VRTRasterBand>
765    </VRTDataset>
766
767In addition to the subclass specification (VRTDerivedRasterBand) and
768the PixelFunctionType value, there is another new parameter that can come
769in handy: SourceTransferType.  Typically the source rasters are obtained
770using the data type of the derived band.  There might be times,
771however, when you want the pixel function to have access to
772higher resolution source data than the data type being generated.
773For example, you might have a derived band of type "Float", which takes
774a single source of type "CFloat32" or "CFloat64", and returns the imaginary
775portion.  To accomplish this, set the SourceTransferType to "CFloat64".
776Otherwise the source would be converted to "Float" prior to
777calling the pixel function, and the imaginary portion would be lost.
778
779.. code-block:: xml
780
781    <VRTDataset rasterXSize="1000" rasterYSize="1000">
782        <VRTRasterBand dataType="Float32" band="1" subClass="VRTDerivedRasterBand">
783            <Description>Magnitude</Description>
784            <PixelFunctionType>MyFirstFunction</PixelFunctionType>
785            <SourceTransferType>CFloat64</SourceTransferType>
786            ...
787
788Default Pixel Functions
789+++++++++++++++++++++++
790
791Starting with GDAL 2.2, GDAL provides a set of default pixel functions that can be used without writing new code:
792
793- **real**: extract real part from a single raster band (just a copy if the input is non-complex)
794- **imag**: extract imaginary part from a single raster band (0 for non-complex)
795- **complex**: make a complex band merging two bands used as real and imag values
796- **mod**: extract module from a single raster band (real or complex)
797- **phase**: extract phase from a single raster band [-PI,PI] (0 or PI for non-complex)
798- **conj**: computes the complex conjugate of a single raster band (just a copy if the input is non-complex)
799- **sum**: sum 2 or more raster bands
800- **diff**: computes the difference between 2 raster bands (b1 - b2)
801- **mul**: multiply 2 or more raster bands
802- **cmul**: multiply the first band for the complex conjugate of the second
803- **inv**: inverse (1./x). Note: no check is performed on zero division
804- **intensity**: computes the intensity Re(x*conj(x)) of a single raster band (real or complex)
805- **sqrt**:perform the square root of a single raster band (real only)
806- **log10**: compute the logarithm (base 10) of the abs of a single raster band (real or complex): log10( abs( x ) )
807- **dB**: perform conversion to dB of the abs of a single raster band (real or complex): 20. * log10( abs( x ) )
808- **dB2amp**: perform scale conversion from logarithmic to linear (amplitude) (i.e. 10 ^ ( x / 20 ) ) of a single raster band (real only)
809- **dB2pow**: perform scale conversion from logarithmic to linear (power) (i.e. 10 ^ ( x / 10 ) ) of a single raster band (real only)
810
811Writing Pixel Functions
812+++++++++++++++++++++++
813
814To register this function with GDAL (prior to accessing any VRT datasets
815with derived bands that use this function), an application calls
816GDALAddDerivedBandPixelFunc with a key and a GDALDerivedPixelFunc:
817
818.. code-block:: cpp
819
820    GDALAddDerivedBandPixelFunc("MyFirstFunction", TestFunction);
821
822A good time to do this is at the beginning of an application when the
823GDAL drivers are registered.
824
825GDALDerivedPixelFunc is defined with a signature similar to IRasterIO:
826
827@param papoSources A pointer to packed rasters; one per source.  The
828datatype of all will be the same, specified in the eSrcType parameter.
829
830@param nSources The number of source rasters.
831
832@param pData The buffer into which the data should be read, or from which
833it should be written.  This buffer must contain at least nBufXSize *
834nBufYSize words of type eBufType.  It is organized in left to right,
835top to bottom pixel order.  Spacing is controlled by the nPixelSpace,
836and nLineSpace parameters.
837
838@param nBufXSize The width of the buffer image into which the desired
839region is to be read, or from which it is to be written.
840
841@param nBufYSize The height of the buffer image into which the desired
842region is to be read, or from which it is to be written.
843
844@param eSrcType The type of the pixel values in the papoSources raster
845array.
846
847@param eBufType The type of the pixel values that the pixel function must
848generate in the pData data buffer.
849
850@param nPixelSpace The byte offset from the start of one pixel value in
851pData to the start of the next pixel value within a scanline.  If
852defaulted (0) the size of the datatype eBufType is used.
853
854@param nLineSpace The byte offset from the start of one scanline in
855pData to the start of the next.
856
857@return CE_Failure on failure, otherwise CE_None.
858
859.. code-block:: cpp
860
861    typedef CPLErr
862    (*GDALDerivedPixelFunc)(void **papoSources, int nSources, void *pData,
863                            int nXSize, int nYSize,
864                            GDALDataType eSrcType, GDALDataType eBufType,
865                            int nPixelSpace, int nLineSpace);
866
867The following is an implementation of the pixel function:
868
869.. code-block:: cpp
870
871    #include "gdal.h"
872
873    CPLErr TestFunction(void **papoSources, int nSources, void *pData,
874                        int nXSize, int nYSize,
875                        GDALDataType eSrcType, GDALDataType eBufType,
876                        int nPixelSpace, int nLineSpace)
877    {
878        int ii, iLine, iCol;
879        double pix_val;
880        double x0, x3, x4, x8;
881
882        // ---- Init ----
883        if (nSources != 4) return CE_Failure;
884
885        // ---- Set pixels ----
886        for( iLine = 0; iLine < nYSize; iLine++ )
887        {
888            for( iCol = 0; iCol < nXSize; iCol++ )
889            {
890                ii = iLine * nXSize + iCol;
891                /* Source raster pixels may be obtained with SRCVAL macro */
892                x0 = SRCVAL(papoSources[0], eSrcType, ii);
893                x3 = SRCVAL(papoSources[1], eSrcType, ii);
894                x4 = SRCVAL(papoSources[2], eSrcType, ii);
895                x8 = SRCVAL(papoSources[3], eSrcType, ii);
896
897                pix_val = sqrt((x3*x3+x4*x4)/(x0*x8));
898
899                GDALCopyWords(&pix_val, GDT_Float64, 0,
900                            ((GByte *)pData) + nLineSpace * iLine + iCol * nPixelSpace,
901                            eBufType, nPixelSpace, 1);
902            }
903        }
904
905        // ---- Return success ----
906        return CE_None;
907    }
908
909Using Derived Bands (with pixel functions in Python)
910----------------------------------------------------
911
912Starting with GDAL 2.2, in addition to pixel functions written in C/C++ as
913documented in the \ref gdal_vrttut_derived_c section, it is possible to use
914pixel functions written in Python. Both `CPython <https://www.python.org/>`_
915and `NumPy <http://www.numpy.org/>`_ are requirements at run-time.
916
917The subelements for VRTRasterBand (whose subclass specification must be
918set to VRTDerivedRasterBand) are :
919
920- **PixelFunctionType** (required): Must be set to a function name that will be defined as a inline Python module in PixelFunctionCode element or as the form "module_name.function_name" to refer to a function in an external Python module
921
922- **PixelFunctionLanguage** (required): Must be set to Python.
923
924- **PixelFunctionArguments** (optional): It is possible to pass arguments to the Python pixel function by defining attributes in the PixelFunctionArguments element.
925
926- **PixelFunctionCode** (required if PixelFunctionType is of the form "function_name", ignored otherwise). The in-lined code of a Python module, that must be at least have a function whose name is given by PixelFunctionType.
927
928- **BufferRadius** (optional, defaults to 0): Amount of extra pixels, with respect to the original RasterIO() request to satisfy, that are fetched at the left, right, bottom and top of the input and output buffers passed to the pixel function. Note that the values of the output buffer in this buffer zone willbe ignored.
929
930The signature of the Python pixel function must have the following arguments:
931
932- **in_ar**: list of input NumPy arrays (one NumPy array for each source)
933- **out_ar**: output NumPy array to fill. The array is initialized at the right dimensions and with the VRTRasterBand.dataType.
934- **xoff**: pixel offset to the top left corner of the accessed region of the band. Generally not needed except if the processing depends on the pixel position in the raster.
935- **yoff** line offset to the top left corner of the accessed region of the band. Generally not needed.
936- **xsize**: width of the region of the accessed region of the band. Can be used together with out_ar.shape[1] to determine the horizontal resampling ratio of the request.
937- **ysize**: height of the region of the accessed region of the band. Can be used together with out_ar.shape[0] to determine the vertical resampling ratio of the request.
938- **raster_xsize**: total with of the raster band. Generally not needed.
939- **raster_ysize**: total with of the raster band. Generally not needed.
940- **buf_radius**: radius of the buffer (in pixels) added to the left, right, top and bottom of in_ar / out_ar. This is the value of the optional BufferRadius element that can be set so that the original pixel request is extended by a given amount of pixels.
941- **gt**: geotransform. Array of 6 double values.
942- **kwargs**: dictionary with user arguments defined in PixelFunctionArguments
943
944The provided ``out_ar`` array must be modified in-place. Any value currently
945returned by the pixel function is ignored.
946
947.. note::
948
949    If wanting to fill ``out_ar`` from another array, use the ``out_ar[:] = ...``
950    syntax.
951
952Examples
953++++++++
954
955VRT that multiplies the values of the source file by a factor of 1.5
956********************************************************************
957
958.. code-block:: xml
959
960    <VRTDataset rasterXSize="20" rasterYSize="20">
961        <SRS>EPSG:26711</SRS>
962        <GeoTransform>440720,60,0,3751320,0,-60</GeoTransform>
963        <VRTRasterBand dataType="Byte" band="1" subClass="VRTDerivedRasterBand">
964            <PixelFunctionType>multiply</PixelFunctionType>
965            <PixelFunctionLanguage>Python</PixelFunctionLanguage>
966            <PixelFunctionArguments factor="1.5"/>
967            <PixelFunctionCode><![CDATA[
968                import numpy as np
969                def multiply(in_ar, out_ar, xoff, yoff, xsize, ysize, raster_xsize,
970                                raster_ysize, buf_radius, gt, **kwargs):
971                    factor = float(kwargs['factor'])
972                    out_ar[:] = np.round_(np.clip(in_ar[0] * factor,0,255))
973                ]]>
974            </PixelFunctionCode>
975            <SimpleSource>
976                <SourceFilename relativeToVRT="1">byte.tif</SourceFilename>
977            </SimpleSource>
978        </VRTRasterBand>
979    </VRTDataset>
980
981VRT that adds 2 (or more) rasters
982*********************************
983
984.. code-block:: xml
985
986    <VRTDataset rasterXSize="20" rasterYSize="20">
987        <SRS>EPSG:26711</SRS>
988        <GeoTransform>440720,60,0,3751320,0,-60</GeoTransform>
989        <VRTRasterBand dataType="Byte" band="1" subClass="VRTDerivedRasterBand">
990            <PixelFunctionType>add</PixelFunctionType>
991            <PixelFunctionLanguage>Python</PixelFunctionLanguage>
992            <PixelFunctionCode><![CDATA[
993                import numpy as np
994                def add(in_ar, out_ar, xoff, yoff, xsize, ysize, raster_xsize,
995                                raster_ysize, buf_radius, gt, **kwargs):
996                    np.round_(np.clip(np.sum(in_ar, axis = 0, dtype = 'uint16'),0,255),
997                            out = out_ar)
998                ]]>
999            </PixelFunctionCode>
1000            <SimpleSource>
1001                <SourceFilename relativeToVRT="1">byte.tif</SourceFilename>
1002            </SimpleSource>
1003            <SimpleSource>
1004                <SourceFilename relativeToVRT="1">byte2.tif</SourceFilename>
1005            </SimpleSource>
1006        </VRTRasterBand>
1007    </VRTDataset>
1008
1009VRT that computes hillshading using an external library
1010*******************************************************
1011
1012.. code-block:: xml
1013
1014    <VRTDataset rasterXSize="121" rasterYSize="121">
1015        <SRS>EPSG:4326</SRS>
1016        <GeoTransform>-80.004166666666663,0.008333333333333,0,
1017        44.004166666666663,0,-0.008333333333333</GeoTransform>
1018        <VRTRasterBand dataType="Byte" band="1" subClass="VRTDerivedRasterBand">
1019            <ColorInterp>Gray</ColorInterp>
1020            <SimpleSource>
1021                <SourceFilename relativeToVRT="1">n43.dt0</SourceFilename>
1022            </SimpleSource>
1023            <PixelFunctionLanguage>Python</PixelFunctionLanguage>
1024            <PixelFunctionType>hillshading.hillshade</PixelFunctionType>
1025            <PixelFunctionArguments scale="111120" z_factor="30" />
1026            <BufferRadius>1</BufferRadius>
1027            <SourceTransferType>Int16</SourceTransferType>
1028        </VRTRasterBand>
1029    </VRTDataset>
1030
1031with hillshading.py:
1032
1033.. code-block:: python
1034
1035    # Licence: X/MIT
1036    # Copyright 2016, Even Rouault
1037    import math
1038
1039    def hillshade_int(in_ar, out_ar, xoff, yoff, xsize, ysize, raster_xsize,
1040                            raster_ysize, radius, gt, z, scale):
1041        ovr_scale_x = float(out_ar.shape[1] - 2 * radius) / xsize
1042        ovr_scale_y = float(out_ar.shape[0] - 2 * radius) / ysize
1043        ewres = gt[1] / ovr_scale_x
1044        nsres = gt[5] / ovr_scale_y
1045        inv_nsres = 1.0 / nsres
1046        inv_ewres = 1.0 / ewres
1047
1048        az = 315
1049        alt = 45
1050        degreesToRadians = math.pi / 180
1051
1052        sin_alt = math.sin(alt * degreesToRadians)
1053        azRadians = az * degreesToRadians
1054        z_scale_factor = z / (8 * scale)
1055        cos_alt_mul_z_scale_factor = \
1056                math.cos(alt * degreesToRadians) * z_scale_factor
1057        cos_az_mul_cos_alt_mul_z_scale_factor_mul_254 = \
1058                    254 * math.cos(azRadians) * cos_alt_mul_z_scale_factor
1059        sin_az_mul_cos_alt_mul_z_scale_factor_mul_254 = \
1060                    254 * math.sin(azRadians) * cos_alt_mul_z_scale_factor
1061        square_z_scale_factor = z_scale_factor * z_scale_factor
1062        sin_alt_mul_254 = 254.0 * sin_alt
1063
1064        for j in range(radius, out_ar.shape[0]-radius):
1065            win_line = in_ar[0][j-radius:j+radius+1,:]
1066            for i in range(radius, out_ar.shape[1]-radius):
1067                win = win_line[:,i-radius:i+radius+1].tolist()
1068                x = inv_ewres * ((win[0][0] + win[1][0] + win[1][0] + win[2][0])-\
1069                                (win[0][2] + win[1][2] + win[1][2] + win[2][2]))
1070                y = inv_nsres * ((win[2][0] + win[2][1] + win[2][1] + win[2][2])-\
1071                                (win[0][0] + win[0][1] + win[0][1] + win[0][2]))
1072                xx_plus_yy = x * x + y * y
1073                cang_mul_254 = (sin_alt_mul_254 - \
1074                    (y * cos_az_mul_cos_alt_mul_z_scale_factor_mul_254 - \
1075                        x * sin_az_mul_cos_alt_mul_z_scale_factor_mul_254)) / \
1076                    math.sqrt(1 + square_z_scale_factor * xx_plus_yy)
1077                if cang_mul_254 < 0:
1078                    out_ar[j,i] = 1
1079                else:
1080                    out_ar[j,i] = 1 + round(cang_mul_254)
1081
1082    def hillshade(in_ar, out_ar, xoff, yoff, xsize, ysize, raster_xsize,
1083                raster_ysize, radius, gt, **kwargs):
1084        z = float(kwargs['z_factor'])
1085        scale= float(kwargs['scale'])
1086        hillshade_int(in_ar, out_ar, xoff, yoff, xsize, ysize, raster_xsize,
1087                    raster_ysize, radius, gt, z, scale)
1088
1089Python module path
1090++++++++++++++++++
1091
1092When importing modules from inline Python code or when relying on out-of-line
1093code (PixelFunctionType of the form "module_name.function_name"), you need
1094to make sure the modules are accessible through the python path. Note that
1095contrary to the Python interactive interpreter, the current path is not
1096automatically added when used from GDAL. So you may need to define the
1097PYTHONPATH environment variable if you get ModuleNotFoundError exceptions.
1098
1099Security implications
1100*********************
1101
1102The ability to run Python code potentially opens the door to many potential
1103vulnerabilities if the user of GDAL may process untrusted datasets. To avoid
1104such issues, by default, execution of Python pixel function will be disabled.
1105The execution policy can be controlled with the GDAL_VRT_ENABLE_PYTHON
1106configuration option, which can accept 3 values:
1107
1108- YES: all VRT scripts are considered as trusted and their Python pixel functions will be run when pixel operations are involved.
1109- NO: all VRT scripts are considered untrusted, and none Python pixelfunction will be run.
1110- TRUSTED_MODULES (default setting): all VRT scripts with inline Python code in their PixelFunctionCode elements will be considered untrusted and will not be run. VRT scripts that use a PixelFunctionType of the form "module_name.function_name" will be considered as trusted, only if "module_name" is allowed in the GDAL_VRT_TRUSTED_MODULES configuration option. The value of this configuration option is a comma separated listed of trusted module names. The '*' wildcard can be used at the name of a string to match all strings beginning with the substring before the '*' character. For example 'every*' will make 'every.thing' or 'everything' module trusted. '*' can also be used to make all modules to be trusted. The ".*" wildcard can also be used to match exact modules or submodules names. For example 'every.*' will make 'every' and 'every.thing' modules trusted, but not 'everything'.
1111
1112.. _linking_mechanism_to_python_interpreter:
1113
1114Linking mechanism to a Python interpreter
1115*****************************************
1116
1117Currently only CPython 2 and 3 is supported. The GDAL shared object
1118is not explicitly linked at build time to any of the CPython library. When GDAL
1119will need to run Python code, it will first determine if the Python interpreter
1120is loaded in the current process (which is the case if the program is a Python
1121interpreter itself, or if another program, e.g. QGIS, has already loaded the
1122CPython library). Otherwise it will look if the PYTHONSO configuration option is
1123defined. This option can be set to point to the name of the Python library to
1124use, either as a shortname like "libpython2.7.so" if it is accessible through
1125the Linux dynamic loader (so typically in one of the paths in /etc/ld.so.conf or
1126LD_LIBRARY_PATH) or as a full path name like "/usr/lib/x86_64-linux-gnu/libpython2.7.so".
1127The same holds on Windows will shortnames like "python27.dll" if accessible through
1128the PATH or full path names like "c:\\python27\\python27.dll". If the PYTHONSO
1129configuration option is not defined, it will look for a "python" binary in the
1130directories of the PATH and will try to determine the related shared object
1131(it will retry with "python3" if no "python" has been found). If the above
1132was not successful, then a predefined list of shared objects names
1133will be tried. At the time of writing, the order of versions searched is 2.7,
11343.5, 3.6, 3.7, 3.8, 3.9, 3.4, 3.3, 3.2. Enabling debug information (CPL_DEBUG=ON) will
1135show which Python version is used.
1136
1137Just-in-time compilation
1138++++++++++++++++++++++++
1139
1140The use of a just-in-time compiler may significantly speed up execution times.
1141`Numba <http://numba.pydata.org/>`_ has been successfully tested. For
1142better performance, it is recommended to use a offline pixel function so that
1143the just-in-time compiler may cache its compilation.
1144
1145Given the following mandelbrot.py file :
1146
1147.. code-block:: python
1148
1149    # Trick for compatibility with and without numba
1150    try:
1151        from numba import jit
1152        #print('Using numba')
1153        g_max_iterations = 100
1154    except:
1155        class jit(object):
1156            def __init__(self, nopython = True, nogil = True):
1157                pass
1158
1159            def __call__(self, f):
1160                return f
1161
1162        #print('Using non-JIT version')
1163        g_max_iterations = 25
1164
1165    # Use a wrapper for the entry point regarding GDAL, since GDAL cannot access
1166    # the jit decorated function with the expected signature.
1167    def mandelbrot(in_ar, out_ar, xoff, yoff, xsize, ysize, raster_xsize,
1168                            raster_ysize, r, gt, **kwargs):
1169        mandelbrot_jit(out_ar, xoff, yoff, xsize, ysize, raster_xsize, raster_ysize,
1170    g_max_iterations)
1171
1172    # Will make sure that the code is compiled to pure native code without Python
1173    # fallback.
1174    @jit(nopython=True, nogil=True, cache=True)
1175    def mandelbrot_jit(out_ar, xoff, yoff, xsize, ysize, raster_xsize,
1176                            raster_ysize, max_iterations):
1177        ovr_factor_y = float(out_ar.shape[0]) / ysize
1178        ovr_factor_x = float(out_ar.shape[1]) / xsize
1179        for j in range( out_ar.shape[0]):
1180            y0 = 2.0 * (yoff + j / ovr_factor_y) / raster_ysize - 1
1181            for i in range(out_ar.shape[1]):
1182                x0 = 3.5 * (xoff + i / ovr_factor_x) / raster_xsize - 2.5
1183                x = 0.0
1184                y = 0.0
1185                x2 = 0.0
1186                y2 = 0.0
1187                iteration = 0
1188                while x2 + y2 < 4 and iteration < max_iterations:
1189                    y = 2*x*y + y0
1190                    x = x2 - y2 + x0
1191                    x2 = x * x
1192                    y2 = y * y
1193                    iteration += 1
1194
1195                out_ar[j][i] = iteration * 255 / max_iterations
1196
1197The following VRT file can be used (to be opened with QGIS for example)
1198
1199.. code-block:: xml
1200
1201    <VRTDataset rasterXSize="100000000" rasterYSize="100000000">
1202        <VRTRasterBand dataType="Byte" band="1" subClass="VRTDerivedRasterBand">
1203            <PixelFunctionLanguage>Python</PixelFunctionLanguage>
1204            <PixelFunctionType>mandelbrot.mandelbrot</PixelFunctionType>
1205            <Metadata>
1206            <MDI key="STATISTICS_MAXIMUM">255</MDI>
1207            <MDI key="STATISTICS_MEAN">127</MDI>
1208            <MDI key="STATISTICS_MINIMUM">0</MDI>
1209            <MDI key="STATISTICS_STDDEV">127</MDI>
1210            </Metadata>
1211            <ColorInterp>Gray</ColorInterp>
1212            <Histograms>
1213            <HistItem>
1214                <HistMin>-0.5</HistMin>
1215                <HistMax>255.5</HistMax>
1216                <BucketCount>256</BucketCount>
1217                <IncludeOutOfRange>0</IncludeOutOfRange>
1218                <Approximate>1</Approximate>
1219                <HistCounts>0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|
1220        0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|
1221        0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|
1222        0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|
1223        0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|
1224        0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|
1225        0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0</HistCounts>
1226            </HistItem>
1227            </Histograms>
1228        </VRTRasterBand>
1229    </VRTDataset>
1230
1231.. _gdal_vrttut_warped:
1232
1233Warped VRT
1234----------
1235
1236A warped VRT is a VRTDataset with subClass="VRTWarpedDataset". It has a
1237GDALWarpOptions element which describe the warping options.
1238
1239.. code-block:: xml
1240
1241    <VRTDataset rasterXSize="20" rasterYSize="20" subClass="VRTWarpedDataset">
1242        <SRS>PROJCS["NAD27 / UTM zone 11N",GEOGCS["NAD27",DATUM["North_American_Datum_1927",SPHEROID["Clarke 1866",6378206.4,294.9786982138982,AUTHORITY["EPSG","7008"]],AUTHORITY["EPSG","6267"]],PRIMEM["Greenwich",0,AUTHORITY["EPSG","8901"]],UNIT["degree",0.0174532925199433,AUTHORITY["EPSG","9122"]],AUTHORITY["EPSG","4267"]],PROJECTION["Transverse_Mercator"],PARAMETER["latitude_of_origin",0],PARAMETER["central_meridian",-117],PARAMETER["scale_factor",0.9996],PARAMETER["false_easting",500000],PARAMETER["false_northing",0],UNIT["metre",1,AUTHORITY["EPSG","9001"]],AXIS["Easting",EAST],AXIS["Northing",NORTH],AUTHORITY["EPSG","26711"]]</SRS>
1243        <GeoTransform>  4.4072000000000000e+05,  6.0000000000000000e+01,  0.0000000000000000e+00,  3.7513200000000000e+06,  0.0000000000000000e+00, -6.0000000000000000e+01</GeoTransform>
1244        <Metadata>
1245            <MDI key="AREA_OR_POINT">Area</MDI>
1246        </Metadata>
1247        <VRTRasterBand dataType="Byte" band="1" subClass="VRTWarpedRasterBand">
1248            <ColorInterp>Gray</ColorInterp>
1249        </VRTRasterBand>
1250        <BlockXSize>20</BlockXSize>
1251        <BlockYSize>20</BlockYSize>
1252        <GDALWarpOptions>
1253            <WarpMemoryLimit>6.71089e+07</WarpMemoryLimit>
1254            <ResampleAlg>NearestNeighbour</ResampleAlg>
1255            <WorkingDataType>Byte</WorkingDataType>
1256            <Option name="INIT_DEST">0</Option>
1257            <SourceDataset relativeToVRT="1">byte.vrt</SourceDataset>
1258            <Transformer>
1259            <ApproxTransformer>
1260                <MaxError>0.125</MaxError>
1261                <BaseTransformer>
1262                <GenImgProjTransformer>
1263                    <SrcGeoTransform>440720,60,0,3751320,0,-60</SrcGeoTransform>
1264                    <SrcInvGeoTransform>-7345.33333333333303,0.0166666666666666664,0,62522,0,-0.0166666666666666664</SrcInvGeoTransform>
1265                    <DstGeoTransform>440720,60,0,3751320,0,-60</DstGeoTransform>
1266                    <DstInvGeoTransform>-7345.33333333333303,0.0166666666666666664,0,62522,0,-0.0166666666666666664</DstInvGeoTransform>
1267                </GenImgProjTransformer>
1268                </BaseTransformer>
1269            </ApproxTransformer>
1270            </Transformer>
1271            <BandList>
1272            <BandMapping src="1" dst="1" />
1273            </BandList>
1274        </GDALWarpOptions>
1275    </VRTDataset>
1276
1277.. _gdal_vrttut_pansharpen:
1278
1279Pansharpened VRT
1280----------------
1281
1282.. versionadded:: 2.1
1283
1284A VRT can describe a dataset resulting from a
1285`pansharpening operation <https://en.wikipedia.org/wiki/Pansharpened_image>`_
1286The pansharpening VRT combines a panchromatic band with several spectral bands
1287of lower resolution to generate output spectral bands of the same resolution as
1288the panchromatic band.
1289
1290VRT pansharpening assumes that the panchromatic and spectral bands have the same
1291projection (or no projection). If that is not the case, reprojection must be done in a prior step.
1292Bands might have different geotransform matrices, in which case, by default, the
1293resulting dataset will have as extent the union of all extents.
1294
1295Currently the only supported pansharpening algorithm is a "weighted" Brovey algorithm.
1296The general principle of this algorithm is that, after resampling the spectral bands
1297to the resolution of the panchromatic band, a pseudo panchromatic intensity is computed
1298from a weighted average of the spectral bands. Then the output value of the spectral
1299band is its input value multiplied by the ratio of the real panchromatic intensity
1300over the pseudo panchromatic intensity.
1301
1302Corresponding pseudo code:
1303
1304::
1305
1306    pseudo_panchro[pixel] = sum(weight[i] * spectral[pixel][i] for i=0 to nb_spectral_bands-1)
1307    ratio = panchro[pixel] / pseudo_panchro[pixel]
1308    for i=0 to nb_spectral_bands-1:
1309        output_value[pixel][i] = input_value[pixel][i] * ratio
1310
1311A valid pansharpened VRT must declare subClass="VRTPansharpenedDataset" as an
1312attribute of the VRTDataset top element. The VRTDataset element must have a
1313child **PansharpeningOptions** element. This PansharpeningOptions element must have
1314a **PanchroBand** child element and one of several **SpectralBand** elements.
1315PanchroBand and SpectralBand elements must have at least a **SourceFilename** child
1316element to specify the name of the dataset. They may also have a **SourceBand** child
1317element to specify the number of the band in the dataset (starting with 1). If not
1318specify, the first band will be assumed.
1319
1320The SpectralBand element must generally have a **dstBand** attribute to specify the
1321number of the output band (starting with 1) to which the input spectral band must be mapped.
1322If the attribute is not specified, the spectral band will be taken into account
1323in the computation of the pansharpening, but not exposed as an output band.
1324
1325Panchromatic and spectral bands should generally come from different datasets,
1326since bands of a GDAL dataset are assumed to have all the same dimensions.
1327Spectral bands themselves can come from one or several datasets. The only
1328constraint is that they have all the same dimensions.
1329
1330An example of a minimalist working VRT is the following. It will generates a dataset with 3 output
1331bands corresponding to the 3 input spectral bands of multispectral.tif, pansharpened
1332with panchromatic.tif.
1333
1334.. code-block:: xml
1335
1336    <VRTDataset subClass="VRTPansharpenedDataset">
1337        <PansharpeningOptions>
1338            <PanchroBand>
1339                <SourceFilename relativeToVRT="1">panchromatic.tif</SourceFilename>
1340                <SourceBand>1</SourceBand>
1341            </PanchroBand>
1342            <SpectralBand dstBand="1">
1343                <SourceFilename relativeToVRT="1">multispectral.tif</SourceFilename>
1344                <SourceBand>1</SourceBand>
1345            </SpectralBand>
1346            <SpectralBand dstBand="2">
1347                <SourceFilename relativeToVRT="1">multispectral.tif</SourceFilename>
1348                <SourceBand>2</SourceBand>
1349            </SpectralBand>
1350            <SpectralBand dstBand="3">
1351                <SourceFilename relativeToVRT="1">multispectral.tif</SourceFilename>
1352                <SourceBand>3</SourceBand>
1353            </SpectralBand>
1354        </PansharpeningOptions>
1355    </VRTDataset>
1356
1357In the above example, 3 output pansharpend bands will be created from the 3 declared
1358input spectral bands. The weights will be 1/3. Cubic resampling will be used. The
1359projection and geotransform from the panchromatic band will be reused for the VRT
1360dataset.
1361
1362It is possible to create more explicit and declarative pansharpened VRT, allowing
1363for example to only output part of the input spectral bands (e.g. only RGB when
1364the input multispectral dataset is RGBNir). It is also possible to add "classic"
1365VRTRasterBands, in addition to the pansharpened bands.
1366
1367In addition to the above mentioned required PanchroBand and SpectralBand elements,
1368the PansharpeningOptions element may have the following children elements :
1369
1370- **Algorithm**: to specify the pansharpening algorithm. Currently, only WeightedBrovey is supported.
1371- **AlgorithmOptions**: to specify the options of the pansharpening algorithm. With WeightedBrovey algorithm, the only supported option is a **Weights** child element whose content must be a comma separated list of real values assigning the weight of each of the declared input spectral bands. There must be as many values as declared input spectral bands.
1372- **Resampling**: the resampling kernel used to resample the spectral bands to the resolution of the panchromatic band. Can be one of Cubic (default), Average, Near, CubicSpline, Bilinear, Lanczos.
1373- **NumThreads**: Number of worker threads. Integer number or ALL_CPUS. If this option is not set, the GDAL_NUM_THREADS configuration option will be queried (its value can also be set to an integer or ALL_CPUS)
1374- **BitDepth**: Can be used to specify the bit depth of the panchromatic and spectral bands (e.g. 12). If not specified, the NBITS metadata item from the panchromatic band will be used if it exists.
1375- **NoData**: Nodata value to take into account for panchromatic and spectral bands. It will be also used as the output nodata value. If not specified and all input bands have the same nodata value, it will be implicitly used (unless the special None value is put in NoData to prevent that).
1376- **SpatialExtentAdjustment**: Can be one of **Union** (default), **Intersection**, **None** or **NoneWithoutWarning**. Controls the behavior when panchromatic and spectral bands have not the same geospatial extent. By default, Union will take the union of all spatial extents. Intersection the intersection of all spatial extents. None will not proceed to any adjustment at all (might be useful if the geotransform are somehow dummy, and the top-left and bottom-right corners of all bands match), but will emit a warning. NoneWithoutWarning is the same as None, but in a silent way.
1377
1378The below examples creates a VRT dataset with 4 bands. The first band is the
1379panchromatic band. The 3 following bands are than red, green, blue pansharpened
1380bands computed from a multispectral raster with red, green, blue and near-infrared
1381bands. The near-infrared bands is taken into account for the computation of the
1382pseudo panchromatic intensity, but not bound to an output band.
1383
1384.. code-block:: xml
1385
1386    <VRTDataset rasterXSize="800" rasterYSize="400" subClass="VRTPansharpenedDataset">
1387        <SRS>WGS84</SRS>
1388        <GeoTransform>-180, 0.45, 0, 90, 0, -0.45</GeoTransform>
1389        <Metadata>
1390            <MDI key="DESCRIPTION">Panchromatic band + pan-sharpened red, green and blue bands</MDI>
1391        </Metadata>
1392        <VRTRasterBand dataType="Byte" band="1" >
1393            <SimpleSource>
1394                <SourceFilename relativeToVRT="1">world_pan.tif</SourceFilename>
1395                <SourceBand>1</SourceBand>
1396            </SimpleSource>
1397        </VRTRasterBand>
1398        <VRTRasterBand dataType="Byte" band="2" subClass="VRTPansharpenedRasterBand">
1399            <ColorInterp>Red</ColorInterp>
1400        </VRTRasterBand>
1401        <VRTRasterBand dataType="Byte" band="3" subClass="VRTPansharpenedRasterBand">
1402            <ColorInterp>Green</ColorInterp>
1403        </VRTRasterBand>
1404        <VRTRasterBand dataType="Byte" band="4" subClass="VRTPansharpenedRasterBand">
1405            <ColorInterp>Blue</ColorInterp>
1406        </VRTRasterBand>
1407        <BlockXSize>256</BlockXSize>
1408        <BlockYSize>256</BlockYSize>
1409        <PansharpeningOptions>
1410            <Algorithm>WeightedBrovey</Algorithm>
1411            <AlgorithmOptions>
1412                <Weights>0.25,0.25,0.25,0.25</Weights>
1413            </AlgorithmOptions>
1414            <Resampling>Cubic</Resampling>
1415            <NumThreads>ALL_CPUS</NumThreads>
1416            <BitDepth>8</BitDepth>
1417            <NoData>0</NoData>
1418            <SpatialExtentAdjustment>Union</SpatialExtentAdjustment>
1419            <PanchroBand>
1420                <SourceFilename relativeToVRT="1">world_pan.tif</SourceFilename>
1421                <SourceBand>1</SourceBand>
1422            </PanchroBand>
1423            <SpectralBand dstBand="2">
1424                <SourceFilename relativeToVRT="1">world_rgbnir.tif</SourceFilename>
1425                <SourceBand>1</SourceBand>
1426            </SpectralBand>
1427            <SpectralBand dstBand="3">
1428                <SourceFilename relativeToVRT="1">world_rgbnir.tif</SourceFilename>
1429                <SourceBand>2</SourceBand>
1430            </SpectralBand>
1431                <SpectralBand dstBand="4">
1432                <SourceFilename relativeToVRT="1">world_rgbnir.tif</SourceFilename>
1433                <SourceBand>3</SourceBand>
1434            </SpectralBand>
1435            <SpectralBand> <!-- note the absence of the dstBand attribute, to indicate
1436                                that the NIR band is not bound to any output band -->
1437                <SourceFilename relativeToVRT="1">world_rgbnir.tif</SourceFilename>
1438                <SourceBand>4</SourceBand>
1439            </SpectralBand>
1440        </PansharpeningOptions>
1441    </VRTDataset>
1442
1443Multidimensional VRT
1444---------------------
1445
1446.. versionadded:: 3.1
1447
1448See the dedicated :ref:`vrt_multidimensional` page.
1449
1450.. toctree::
1451   :maxdepth: 1
1452   :hidden:
1453
1454   vrt_multidimensional
1455
1456vrt:// connection string
1457------------------------
1458
1459.. versionadded:: 3.1
1460
1461In some contexts, it might be useful to benefit from features of VRT without
1462having to create a file or to provide the rather verbose VRT XML content as
1463the connection string. For that purpose, the following URI syntax is supported for
1464the dataset name since GDAL 3.1
1465
1466::
1467
1468    vrt://{path_to_gdal_dataset}?[bands=num1,...,numN]
1469
1470For example:
1471
1472::
1473
1474    vrt://my.tif?bands=3,2,1
1475
1476The only supported option currently is bands. Other may be added in the future.
1477
1478The effect of this option is to change the band composition. The values specified
1479are the source band numbers (between 1 and N), possibly out-of-order or with repetitions.
1480The ``mask`` value can be used to specify the global mask band. This can also
1481be seen as an equivalent of running `gdal_translate -of VRT -b num1 ... -b numN`.
1482
1483Multi-threading issues
1484----------------------
1485
1486.. warning::
1487
1488    The below section applies to GDAL <= 2.2. Starting with GDAL 2.3, the use
1489    of VRT datasets is subject to the standard GDAL dataset multi-threaded rules
1490    (that is a VRT dataset handle may only be used by a same thread at a time,
1491    but you may open several dataset handles on the same VRT file and use them
1492    in different threads)
1493
1494When using VRT datasets in a multi-threading environment, you should be
1495careful to open the VRT dataset by the thread that will use it afterwards. The
1496reason for that is that the VRT dataset uses GDALOpenShared when opening the
1497underlying datasets. So, if you open twice the same VRT dataset by the same
1498thread, both VRT datasets will share the same handles to the underlying
1499datasets.
1500
1501The shared attribute, on the SourceFilename indicates whether the
1502dataset should be shared (value is 1) or not (value is 0). The default is 1.
1503If several VRT datasets referring to the same underlying sources are used in a multithreaded context,
1504shared should be set to 0. Alternatively, the VRT_SHARED_SOURCE configuration
1505option can be set to 0 to force non-shared mode.
1506
1507Performance considerations
1508--------------------------
1509
1510A VRT can reference many (hundreds, thousands, or more) datasets. Due to
1511operating system limitations, and for performance at opening time, it is
1512not reasonable/possible to open them all at the same time. GDAL has a "pool"
1513of datasets opened by VRT files whose maximum limit is 100 by default. When it
1514needs to access a dataset referenced by a VRT, it checks if it is already in
1515the pool of open datasets. If not, when the pool has reached its limit, it closes
1516the least recently used dataset to be able to open the new one. This maximum
1517limit of the pool can be increased by setting the GDAL_MAX_DATASET_POOL_SIZE
1518configuration option to a bigger value. Note that a typical user process on
1519Linux is limited to 1024 simultaneously opened files, and you should let some
1520margin for shared libraries, etc...
1521gdal_translate and gdalwarp, by default, increase the pool size to 450.
1522
1523Driver capabilities
1524-------------------
1525
1526.. supports_createcopy::
1527
1528.. supports_create::
1529
1530.. supports_georeferencing::
1531
1532.. supports_virtualio::
1533