> For the complete documentation index, see [llms.txt](https://help.felt.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://help.felt.com/upload-anything/stream-large-rasters/vrt-mosaics.md).

# VRT mosaics

Combine raster files into one layer with a GDAL Virtual Raster (VRT) mosaic. Upload the VRT or stream it from your bucket.

A [Virtual Raster (VRT)](https://gdal.org/en/stable/drivers/raster/vrt.html) is a small XML file that lists several source rasters and describes how they fit together. When your imagery or elevation data is split across many files, a VRT lets Felt show them as one seamless layer.

## Two ways to combine rasters

There are two ways to turn many raster files into one layer:

1. Merge locally, then upload. Use GDAL, QGIS, or [rasterio](https://rasterio.readthedocs.io/) to merge your files into one large raster, and upload it. This is straightforward for smaller datasets, but the merged file can become very large and slow to produce.
2. Build a VRT and upload it. Host your source rasters where Felt can reach them, such as a bucket or an HTTPS URL, build a VRT that points to them, and upload only the VRT. Felt reads the VRT, fetches the sources, and converts the mosaic into one tiled raster for you.

For many files or [Cloud Optimized GeoTIFFs (COGs)](/upload-anything/stream-large-rasters/cloud-optimized-geotiffs.md), we recommend a VRT. The VRT is only a few kilobytes, the source pixels stay in their original files, and you can rebuild the VRT without merging your imagery yourself.

VRT mosaics work best for rasters that cover a contiguous area at similar or identical resolution, such as tiled digital elevation models (DEMs) and digital orthophoto quarter quads (DOQQs). They aren't a good fit for sparse datasets scattered across a large area.

## Create a VRT

### Step 1: Use one projection for all sources

Every source raster in a VRT must use the same projection, or coordinate reference system (CRS). If your sources use different projections, reproject the mismatched ones to a common CRS, for example with [`gdalwarp`](https://gdal.org/en/stable/programs/gdalwarp.html):

```bash
gdalwarp -t_srs EPSG:3857 source_in_other_crs.tif source_reprojected.tif
```

### Step 2: Give your sources overviews

Overviews are precomputed lower-resolution copies of a raster that let Felt stream the mosaic efficiently when you're zoomed out. `gdalbuildvrt` writes the `<OverviewList>` tag into the VRT only when the source rasters already have overviews. Without them, the VRT doesn't stream well in Felt.

Store the sources as [Cloud Optimized GeoTIFFs](/upload-anything/stream-large-rasters/cloud-optimized-geotiffs.md), which include overviews, or add overviews with [`gdaladdo`](https://gdal.org/en/stable/programs/gdaladdo.html):

```bash
gdaladdo -r bilinear file1.tif 2 4 8 16 32
```

### Step 3: List source paths Felt can reach

List the paths to your source rasters in a text file, one per line. Felt can't read files on your computer, so a VRT with local disk paths appears empty in Felt. For remote sources, give each path a [GDAL virtual file system](https://gdal.org/en/stable/user/virtual_file_systems.html) prefix, so Felt knows how to fetch it:

* `/vsicurl/https://host/path/file.tif` for files at an HTTPS URL
* `/vsis3/bucket/key.tif` for files in Amazon S3

For example, a `files.txt` for sources in Amazon S3:

```
/vsis3/my-bucket/imagery/file1.tif
/vsis3/my-bucket/imagery/file2.tif
```

### Step 4: Build the VRT with gdalbuildvrt

The [`gdalbuildvrt`](https://gdal.org/en/stable/programs/gdalbuildvrt.html) command in the [GDAL](https://gdal.org/en/stable/download.html) command-line tools builds the VRT from your list:

```bash
gdalbuildvrt -input_file_list files.txt -r bilinear mosaic.vrt
```

The `-r` flag sets the resampling method for overviews and for reading between resolutions. Use `bilinear` for continuous data, such as elevation or temperature, and `nearest` for categorical or integer data.

Then open the VRT in a text editor and check the `relativeToVRT` attribute on each `<SourceFilename>`:

* `relativeToVRT="0"` means the path is absolute. Use it for `/vsicurl/` and `/vsis3/` paths.
* `relativeToVRT="1"` means the path is relative to the VRT file's own location.

### Step 5: Precompute statistics

When you upload a VRT, Felt calculates summary statistics (min, max, mean, and standard deviation) across the whole mosaic, so it can choose color ramps and styling. For a large mosaic, this can take a long time or fail.

To avoid this, precompute exact statistics on each source raster and store the values in the files. Computing statistics on the VRT itself also helps:

```bash
gdalinfo -stats mosaic.vrt
```

For more on optimizing large mosaics, see [Streaming performance](/upload-anything/stream-large-rasters/cloud-optimized-geotiffs.md#streaming-performance).

## Upload a VRT

Once your VRT points to sources Felt can reach, upload the `.vrt` file like any other raster. Felt reads the VRT, fetches the source rasters, and shows them as one mosaicked layer that you can [style](/styling/style-raster-layers.md) like any raster layer. See [Upload files](/upload-anything/files.md).

## Stream a VRT from your bucket

{% hint style="success" %}
Available on the Business and Enterprise plans. [Compare plans](https://felt.com/pricing#compare)
{% endhint %}

Store the VRT in the same bucket as the source rasters it references, and connect that bucket as a data source. When the VRT sits next to its COGs, Felt streams the mosaic directly from them, instead of converting everything into one large COG as it does for an uploaded VRT. See [Stream large rasters](/upload-anything/stream-large-rasters.md).

## Add a VRT with the REST API

{% hint style="success" %}
Available on the Business and Enterprise plans. [Compare plans](https://felt.com/pricing#compare)
{% endhint %}

You can also add a VRT stored in your bucket to a map with the REST API's upload endpoint. Pass the VRT's URL as `import_url`, and Felt resolves and mosaics the source rasters as it does for a VRT uploaded in Felt.

```bash
curl -X POST "https://felt.com/api/v2/maps/<MAP_ID>/upload" \
  -H "Authorization: Bearer <YOUR_API_TOKEN>" \
  -H "Content-Type: application/json" \
  -d '{"import_url": "gs://your-bucket/mosaic.vrt", "name": "Raster mosaic"}'
```

The `import_url` can be a `gs://`, `s3://`, or public `https://` URL. For a private bucket, [connect the bucket as a source](/upload-anything/data-sources/add-a-source.md) with credentials first, and the upload authenticates with that source. A fully public VRT, with `/vsicurl/` source paths, needs no credentials.

For the full reference, see the [REST API upload documentation](https://developers.felt.com/rest-api/uploading-files-and-urls).


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation by asking a question.

Perform an HTTP GET request on the following URL with the `ask` and `goal` query parameters:

```
GET https://help.felt.com/upload-anything/stream-large-rasters/vrt-mosaics.md?ask=<question>&goal=<user_goal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is what the user is ultimately trying to achieve, the reason they need the answer. Sharing it helps GitBook give you a better, more relevant answer. A goal is most helpful when it describes the outcome the user wants rather than restating the question. For example, with `ask=how do I create an API token`, a goal like `automate deployments from our CI pipeline` lets GitBook tailor the answer to that use case.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
