Adding ESRI’s Online World Imagery Dataset to QGIS

ESRI’s ArcGIS Online World Imagery is a high resolution satellite and aerial imagery base map for use in Google Earth, ArcMap and ArcGIS Explorer. The same excellent imagery is used by the Bing Maps Aerial layer. Somewhat surprisingly, World Imagery can also be accessed by QGIS, as it supports ESRI’s map servers that use Representational State Transfer (REST) and Simple Object Assess Protocol (SOAP) standards.

Simply copy and past the following code into the Python Console in QGIS and press return (Plugins – Console):


The code adds an ESRI Online World Imagery base map to QGIS. It has a number of advantages over the popular OpenLayers Plugin that adds various Google, Bing and OpenStreetMap image layers to QGIS. Unlike images downloaded by the OpenLayers plugin the ESRI World Imagery base map is a true Raster who’s attributes are fully editable e.g. brightness, blending mode and transparency can be adjusted. World Imagery can also be printed at a very high resolution with other QGIS layers on a map and without it shifting relative to other layers; a conspicuous problem with OpenLayers that does not use “On the Fly” re-projection and only prints Google, Bing layers at a low resolution. It is an ideal aerial base map.


QGIS: Adding An ArcServer Rest Service

Connecting to ArcGIS “mapserver” layers

Edit: Updated to correct URL

Note: This method has been superseded by a plug-in that adds ESRI imagery and other REST layers via a GUI

46 thoughts on “Adding ESRI’s Online World Imagery Dataset to QGIS

  1. interesting… gdal core dump with my old gdal1.9 on debian wheezy

    #0 0x00007ffff5322cf3 in ?? () from /usr/lib/
    #1 0x00007ffff537ad73 in std::vector<std::string, std::allocator >::~vector() () from /usr/lib/
    #2 0x00007fffea1a8063 in libdap::HTTPConnect::plain_fetch_url(std::string const&) () from /usr/lib/x86_64-linux-gnu/
    #3 0x00007fffea1a8cc0 in libdap::HTTPConnect::fetch_url(std::string const&) () from /usr/lib/x86_64-linux-gnu/
    #4 0x00007fffea19f72e in libdap::Connect::request_version() () from /usr/lib/x86_64-linux-gnu/
    #5 0x00007ffff53c1095 in DODSDataset::connect_to_server() () from /usr/lib/
    #6 0x00007ffff53c6b89 in DODSDataset::Open(GDALOpenInfo*) () from /usr/lib/
    #7 0x00007ffff55bc73b in GDALOpenInternal(GDALOpenInfo&, char const* const*) () from /usr/lib/
    #8 0x00007ffff55bc8d6 in GDALOpenInternal(char const*, GDALAccess, char const* const*) () from /usr/lib/
    #9 0x00007fffd4217333 in QgsGdalProviderBase::gdalOpen (pszFilename=
    0x94e4f98 “;pretty=true”, eAccess=GA_ReadOnly)
    at /home/ginetto/PROGRAMMING/QGIS-2.0-master/src/providers/gdal/qgsgdalproviderbase.cpp:308
    #10 0x00007fffd421918a in QgsGdalProvider::QgsGdalProvider (this=0x19890a0, uri=…, update=false)
    at /home/ginetto/PROGRAMMING/QGIS-2.0-master/src/providers/gdal/qgsgdalprovider.cpp:143
    #11 0x00007fffd42236b4 in classFactory (uri=0x94e3a18) at /home/ginetto/PROGRAMMING/QGIS-2.0-master/src/providers/gdal/qgsgdalprovider.cpp:1882
    #12 0x00007ffff46d057a in QgsProviderRegistry::provider (this=0x1505e10, providerKey=…, dataSource=…)
    at /home/ginetto/PROGRAMMING/QGIS-2.0-master/src/core/qgsproviderregistry.cpp:362
    #13 0x00007ffff4849c4b in QgsRasterLayer::setDataProvider (this=0x94e39e0, provider=…)
    at /home/ginetto/PROGRAMMING/QGIS-2.0-master/src/core/raster/qgsrasterlayer.cpp:654
    #14 0x00007ffff484657b in QgsRasterLayer::QgsRasterLayer (this=0x94e39e0, path=…, baseName=…, loadDefaultStyleFlag=true)
    at /home/ginetto/PROGRAMMING/QGIS-2.0-master/src/core/raster/qgsrasterlayer.cpp:104
    #15 0x00000000005ce4ce in QgisApp::addRasterLayerPrivate (this=0x1167ee0, uri=…, baseName=…, providerKey=…, guiWarning=true, guiUpdate=true)
    at /home/ginetto/PROGRAMMING/QGIS-2.0-master/src/app/qgisapp.cpp:9231
    #16 0x00000000005cea4d in QgisApp::addRasterLayer (this=0x1167ee0, rasterFile=…, baseName=…, guiWarning=true)
    at /home/ginetto/PROGRAMMING/QGIS-2.0-master/src/app/qgisapp.cpp:9304
    #17 0x00000000005fd64b in QgisAppInterface::addRasterLayer (this=0x18878c0, rasterLayerPath=…, baseName=…)
    at /home/ginetto/PROGRAMMING/QGIS-2.0-master/src/app/qgisappinterface.cpp:125
    #18 0x00007fff85f6240b in meth_QgisInterface_addRasterLayer (sipSelf=, sipArgs=
    (‘;pretty=true’, ‘raster’), sipKwds=0x0)
    at /home/ginetto/PROGRAMMING/QGIS-2.0-master/build/python/gui/sip_guipart3.cpp:127961

  2. It does not work for me:

    Cannot open GDAL dataset
    An error occurred while creating a virtual connection to the DAP server:
    Error while reading the URL:
    The OPeNDAP server returned the following message:
    Bad Request:

    I can access the address trough a browser, with a readable response.
    Thanks for any hint.

    • There are ca. 120 maps in all but most require a subscription. I have so far accessed an Aerial Map and a simple Street Map, others maybe accessible too. It’s unlikely the REST request can be modified to access ESRI’s subscription based maps however, as access requires OAuth 2.0 authentication. But it is well worth a try if you already subscribe to ESRI’s map services.

      ESRI: Maps and Map Layers

      Accessing services provided by Esri

  3. Pingback: QGIS OpenLayers alternative: ArcGIS online basemap | QGIS UK

  4. Pingback: Extract Aerial Imagery using QGIS | Question and Answer

    • The code is stored in the python console’s history, you don’t have to type it again. Just reopen the python console and press the Up arrow to access previously entered commands.

  5. I have got a problem with ArcGIS REST API connector, when I would like connect to ArcGIS REST, I have an error message.

    Traceback (most recent call last):
    File “C:/Users/XXXX/.qgis2/python/plugins\connector\”, line 342, in loadTreeView
    return self.warning(_translate(“Connector”, “Url not found.”, None) + ” \nError: ” + e.message)
    TypeError: coercing to Unicode: need string or buffer, MaxRetryError found


    • You might not be using the latest version of GDAL, I’m using 1.11. To check what version you are using, use this command in a Terminal on Linux or Command Prompt in Windows:

      gdalinfo –verison

  6. Is there a way to pull metadata for the imagery? It would be helpful to know the date (or at least the year) that it was produced. I know the information exists, since you can Identify it off of the World Imagery layer in ArcGIS.

  7. Great Post! It worked perfectly fine for me 🙂
    I was also able to export a high resolution image using print composer. Though it took a good 15 minutes for a A0 size, 200 DPI, 1:5000 scale image. But totally worth the wait.

      • The first URL, that connects to ArcGIS On-line, includes the ESRI World Light Grey basemap. Its listed under Canvas as World_Light_Gray_Base.

  8. So i have been using this neat trick for a while, but today it stopped working. I get this error, any ideas..

    “GDAL provider: Cannot open GDAL dataset Invalid dataset dimensions : -2147483648 x -2147483648
    Raster layer: Provider is not valid (provider: gdal, URI:

    • I just noticed this myself with QGIS 2.12, it might be due to QGIS or might be linked to the new version of GDAL, version 1.11.3, that was released in September. Hopefully this gets sorted out soon. I also downgraded the ESRI REST plugin to version 0.1 but the problem remains.

      • I just started using QGIS.. .I’ve been a long time user of ESRI products but I need a free solution.. It’s taking a bit of adjustment but I’m liking it so far.

        I was pulling my hair out trying to figure out how to add a service so thanks for the article! I wouldn’t have ever thought to do it through Python and even if I would have, I probably wouldn’t have gotten the syntax correct.

  9. Pingback: Python: How to Loop Functions in QGIS | gifGuide2Code

  10. Pingback: Añadir mapas base en QGIS de forma sencilla

  11. Hello, was wondering if anyone could help me, when I try to zoom far in the imagery disappears and is replaced with grey pixels that say “map data not yet available”, is this normal?

    • Yes, that’s normal behaviour. If you zoom in too much the imagery will not be displayed. Depending of where in the world you zoom in, you can zoom in to no better than 1:1000 to 1:2500 scale.

  12. Hi there, I use the esri base layer quite often however, when I export my composer map to a .png file, the base map image often changes as if the basemap source changes. Is it possible to fix the basemap so it does not automatically change on export?

    • QGIS now has native support for ESRI REST layers, both feature (vectors) and map server (rasters) layers can be added via the browser panel or via Layer – Add Layer menu. Adding a base layer though QGIS rather than via the plugin might solve your issue.

  13. To echo a previous comment by hfisch that did not get a reply, is there any way to get the date of the image retrieved? That would be helpful for a number of reasons.

  14. Hi. This is awesome. But is there a way to control at what resolution these layers are printed? What i’m trying to say is that these layers look perfect on screen from labels and symbols point of view but when printed all these details are way too small. Unless you lower the print resolution which is
    an unacceptable thing to do as you will get low quality images. 😦

  15. What is the best source for higher resolution imagery? Using this ESRI map is great, but when zooming in more than 2,000:1 it would be nice to have a higher resolution image. When zoomed in this far the Bing map actually looks much crisper than ESRI world imagery, but obviously has issues when used with print composer.

  16. Pingback: Añadir mapas base en QGIS de forma sencilla | TYC GIS Formación

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.