Basemaps in QGIS

19.12.2014 16:47 ·  GIS  ·  qgis, howto

When displaying spatial information, it is desirable to have a “context” — some additional data to help you navigate and make the information more readable. This can include administrative boundaries, hydrology, road networks, etc. Such additional layers are called “basemaps”. The term “basemap” is often used to refer exclusively to services such as Google Maps, BING Maps, OpenStreetMap and so on, but this is not correct.

So what is a basemap? It is a background layer (such as a digital elevation model or topographic map) on which thematic layers are overlaid. The basemap is often used for geographic reference and may include elements of the geodetic network. Very often, aerial or satellite imagery is used as a basemap.

At the same time, the widespread use of different map services as basemaps is explained by their accessibility: all that is needed to use them is an Internet connection and minimal GIS skills, whereas the use of other types of data may require some preparatory work, such as georeferencing.

Let’s see how we can use different map services in QGIS.

Map services can use a number of different protocols. For raster data, the most common are WM(T)S and TMS. QGIS allows you to access base maps using either of these protocols, and this can be done in a number of different ways.

OpenLayers plugin

Probably the most popular and well-known option.

The OpenLayers plugin is available from the official QGIS plugin repository. The plugin allows you to add data from Google Maps, OpenStreetMap, MapQuest, Bing Maps, and some other services as map layers. The plugin is very easy to use: after activating it, a new item, “OpenLayers”, will be added to the “Internet” menu. From this menu, the desired layer can be added to the map.

Unfortunately, there are also limitations and shortcomings (most of which can be explained by the mechanism used by the plugin to create layers), although some of them only affect certain use cases:

QGIS as a WM(T)S/WCS client

QGIS can act as a WMS client and supports protocol versions 1.1, 1.1.1 and 1.3. Support for the WMTS protocol is also implemented (the old WMS-C protocol is supported as well). QGIS also supports WCS versions 1.0.0 and 1.1.1. While WCS is not as well known and popular as WM(T)S, in some cases you can find good basemaps published as WCS. All the information about using WM(T)S and WCS services can be found in the user manual, so I see no point in duplicating it here.

The only “problem” with using WM(T)S/WCS services as a basemap is the relatively small number of public services with global coverage. However, in countries with a strong open data culture, public services supported by the government or local authorities often provide basemaps for a specific area as well as other useful layers (population density, land use, etc.).

GDAL WMS driver

The GDAL library supports over 130 raster data formats, including OGC services. The GDAL WMS driver is used to access different map services. This driver has several “mini-drivers” that allow you to work with different types of web services. Since QGIS uses GDAL to work with raster data, we can use all the features of the GDAL driver in QGIS.

Personally, I don’t see any reason to use GDAL to work with regular WMS services, as they are natively supported in QGIS. But there are other types of services besides WMS: TMS, WorldWind, VirtualEarth, and a few others. The most popular and widely used service, often used to provide basemaps, is the Tile Map Service (TMS). It is used by the OpenStreetMap project and many other popular services, such as Google Maps, Bing Maps, etc. Let’s see how to access the TMS service via GDAL, but keep in mind that the same approach can be used to access other types of services, including WM(T)S.

To work with any service via the GDAL driver, we need to create a special XML file describing that service. The root element of this file is <GDAL_WMS>. Please make sure that there are no spaces or other text before this element.

Then, in the Service element, we need to specify the parameters of the service we are interested in. In addition to this block, the file may contain other elements. Detailed information can be found on the GDAL WMS driver page. Here I will only mention those that are needed to add layers in QGIS:

The XML file can also contain other elements, the most useful being:

Let’s see how to describe a TMS service.

Support for TMS was introduced in GDAL 1.7. In addition to TMS, this mini-driver also supports other tile services with a similar working principle. The Tile Map Service specification can be found here.

A typical tile address looks like this:

http://server.com/${version}/${layer}/${z}/${x}/${y}.${format}

The most important parameters are:

Sometimes we also might need other parameters:

And here is an XML describing OSM tiles (global coverage):

<GDAL_WMS>
  <Service name="TMS">
    <ServerUrl>http://tile.openstreetmap.org/${z}/${x}/${y}.png</ServerUrl>
  </Service>
  <DataWindow>
    <UpperLeftX>-20037508.34</UpperLeftX>
    <UpperLeftY>20037508.34</UpperLeftY>
    <LowerRightX>20037508.34</LowerRightX>
    <LowerRightY>-20037508.34</LowerRightY>
    <TileLevel>18</TileLevel>
    <TileCountX>1</TileCountX>
    <TileCountY>1</TileCountY>
    <YOrigin>top</YOrigin>
  </DataWindow>
  <Projection>EPSG:3857</Projection>
  <BlockSizeX>256</BlockSizeX>
  <BlockSizeY>256</BlockSizeY>
  <BandsCount>3</BandsCount>
</GDAL_WMS>

Other tile services are described in the same way.

To load such layers into QGIS, you need to create a corresponding XML file and open it as a normal raster. If the file contains a cache element and the cache contains data and is accessible, the layer will load even without a working internet connection.

A word about ArcGIS Server

Developers of proprietary software often invent their own standards instead of using open, widely accepted standards. The well-known ArcGIS is no exception: although ArcGIS Server supports OGC standards, it is usually configured to work with ESRI’s own REST and SOAP protocols. Fortunately, GDAL comes to the rescue here too.

Actually, ArcGIS Server services are not related to TMS. But there is not much information about using them in QGIS, so this short note will not be superfluous.

First, we need to find the address of the service catalogue (look for “ArcGIS services directory” on the site); usually, it has the address in the form site.domain/ArcGIS/rest/services.

For example, let’s look at the “Maps for Personal Use” service catalogue. In the services list, find the service you need (raster data is of type MapService, but be careful — sometimes vector layers can also be of this type), copy its address and add ?f=json&pretty=true at the end. The last parameter is optional, it indicates the need to provide information in a more readable, formatted form. For the “World_Terrain_Base” layer, the address will look like this

http://server.arcgisonline.com/arcgis/rest/services/World_Terrain_Base/MapServer?f=json&pretty=true

Now that we have a layer URL, we can add it to QGIS. As with most operations, this can be done in a number of ways.

Python console

An option for real geeks. You can load a layer into QGIS using the Python console. To do this, open the console and enter the following code, replacing <service_url> with the actual URL:

iface.addRasterLayer("<service_url>", 'raster')

Despite the obvious drawbacks of this method, for some reason it is the only option that is being metioned everywhere. Someone wrote something stupid, and everyone repeats it and doesn’t even try to think and investigate a bit.

Despite the obvious drawbacks of this method, for some reason it is the only option mentioned everywhere. Someone wrote a stupid thing, and everyone repeats it without even bothering to investigate.

GDAL

Since GDAL and its WMS driver are used to load ArcGIS Server data, we can create an XML file describing the service and open it as a regular raster. To do this, simply run the following command (again, replace the service URL with your own):

gdal_translate "http://server.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer?f=json&pretty=true" WorldTerrain.xml -of WMS

How to find service URL

I often hear the question, “Can I connect the ‘map/service name’ as a WMS/TMS in QGIS? What address should I specify?”. I’ll try to tell you how to find the answer to this question yourself. I use Chrome, but the same approach can be used with other browsers.

Let’s take one of the public maps from the QGISCloud service as an example, for example, this one: https://qgiscloud.com/Niatro/Online_QGIS. Open a browser and activate the developer tools (Ctrl + Shift + I in Chrome) and switch to the “Network” tab. Then navigate to the map page in the browser and zoom in/out a bit. In the developer tools area you will see the requests that the browser is sending to the server.

Network requests to a WMS service
Network requests to a WMS service

Let’s look for image requests among them (by file type, for example) and analyse the address. WMS services usually contain the wms identifier in the address. Here is one such request:

https://qgiscloud.com/Niatro/Online_QGIS/wms?SERVICE=WMS&VERSION=1.1.1&REQUEST=GetMap&FORMAT=image/png&TRANSPARENT=true&LAYERS=OpenStreetMap,OSM Standard,toponimia_area&STYLES=,,&SRS=EPSG:3857&CRS=EPSG:3857&TILED=false&DPI=96&OPACITIES=255,255,255&__t=1708257026654&WIDTH=716&HEIGHT=545&BBOX=-8004528.41682798,-4454125.213525354,-7928751.750161314,-4396446.046858688

We only need the base address of the service, as QGIS will request a list of layers from the server for us and allow us to select the necessary layers in a convenient dialogue. The base address is part of the URL before the first question mark:

https://qgiscloud.com/Niatro/Online_QGIS/wms

This is the address you should specify when creating a new WM(T)S connection in QGIS. As you can see, there is nothing complex here.

Requests to tile-based services are analysed in the same way. Let’s take OpenStreetMap as an example. While the URLs of OSM servers and their format are available on the project’s wiki, let’s see how to get this information using a browser, as this can be useful when working with other services that don’t publish their URLs.

Open a browser and activate developer tools. Go to the OSM page and look for tile requests

Network requests to TMS service
Network requests to TMS service

The tile URL looks like this

http://tiles.openstreetmap.org/13/4199/2692.png

Now let’s ignore the first part of the URL and look at its numeric part, which looks like this

/13/4199/2692.png

From the TMS specification, we know that each tile is described by three coordinates: X and Y define its position on the grid, and Z defines the scale (the larger, the more detailed). We need to determine which part of the address is responsible for which component.

It is better to start with the Z coordinate since, in most cases, this value varies between 0 and 20±2. In our case, this coordinate corresponds to the first number. To be sure, you can change the map scale and check the network request.

Now let’s try panning the map to the left or right, trying not to move it up or down, and look at the network requests again. We can see that the second number in the URL is now changing more, so it’s the X coordinate, and the last one is the Y coordinate.

So the full address for downloading the OSM layer using TMS is

http://tiles.openstreetmap.org/${z}/${x}/${y}.png

this address should be specified in the XML file.

Update from 01.10.2023

ArcGIS REST services are natively supported since QGIS 2.16 “Nødebo”. Connections to such services can be added using the Browser Dock or the Datasource Manager. While it is still possible to add such services using XML files as described above, using the QGIS GUI seems much easier and more user-friendly.

TMS (or, as they are often called, XYZ) services are natively supported since QGIS 2.18 “Las Palmas”. Connections to such services can be added using the Browser dock or the Datasource Manager. There is no need to fiddle with XML files or use 3rd party plugins.

⮜ Prev
Next ⮞