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.
Disclaimer
Before using the information below, be sure to read the licence and terms of service of the map services you are accessing. Misuse of the data may have negative consequences, including legal prosecution.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:
- a map with layers added using the OpenLayers plugin cannot be printed or exported in high quality.
- sometimes, in the Layout Editor and when printing/exporting the map, the basemap is shifted relative to other layers, even though everything is displayed correctly on the map canvas.
- it is not possible to change the rendering settings for OpenLayers layers (e.g., transparency, blending mode, etc.)
- if the plugin is not installed or enabled, a project containing OpenLayers layers will be opened without it, and you will not be warned. This can lead to “silent” data loss
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:
<Service name="TMS">
is a required element. Thename
attribute specifies the mini-driver to use. The supported mini-drivers areWMS
,WorldWind
,TileService
,TMS
,TiledWMS
,VirtualEarth
andAGS
. It is also necessary to provide the following child elements:<ServerUrl>
— the URL of the service in question<DataWindow>
— is a mandatory element. Here we should define the extent of the data and some related information. By adjusting the values of this element, it is possible to limit the area of interest and thus minimise traffic. It consists of the following child elements:<UpperLeftX>
- X coordinate (longitude) of the upper left corner of the extent. Optional parameter, the default value is -180.0. The value is set in units appropriate to the data projection (see below). For example, for WGS84 it should be in degrees, while for WGS84/Pseudo-Mercator it should be in metres.<UpperLeftY>
- Y coordinate (latitude) of the upper left corner of the extent. Optional parameter, default is 90.0<LowerRightX>
— X coordinate (longitude) of the lower right corner of the extent. Optional parameter, the default is 180.0<LowerRightY>
— Y coordinate (latitude) of the lower right corner of the extent. Optional parameter, the default is -90.0<TileLevel>
— the maximum zoom level<TileCountX>
and<TileCountY>
— are used to calculate the size of the image along the X and Y axes<YOrigin>
- defines the position of the Y origin with respect to the tile grid. Possible values aretop
,bottom
anddefault
, where the default behaviour depends on the mini-driver used
<Projection>
— image projection<BandsCount>
— the number of bands/channels. Greyscale images have only one band; RGB — 3 bands; if transparency is supported, then four bands are used<BlockSizeX>
and<BlockSizeY>
— block size in pixels
The XML file can also contain other elements, the most useful being:
<Cache>
- an element describing the local cache. Very useful for working offline<Path>
— optional child element defining the location where cache files should be stored
<MaxConnections>
— maximum number of simultaneous connections to the server<Timeout>
— connection timeout<OfflineMode>
- whether to use offline mode. If set totrue
, no new tiles will be loaded, only data from the cache will be used<VerifyAdviseRead>
- whether the downloaded tiles should be checked for correctness. If set totrue
, each tile will be opened after downloading, and some basic checks will be performed (correct header, size, etc.). If the server is reliable, this can be disabled to reduce CPU load and increase download speed<UserPwd>
- login and password for HTTP authentication in the formatuser:password
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:
${x}
— the X coordinate of the tile${y}
— the Y coordinate of the tile. The countdown starts from the top (OpenStreetMap and other popular services) or bottom (TMS specification) of the tile grid${z}
— Z coordinate of the tile, i.e. its zoom level
Sometimes we also might need other parameters:
${version}
— service version${format}
— image format${layer}
— layer name
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.
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
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.