Connecting to ArcGIS "mapserver" layers

Although Arcgis servers can be configured to provide WMS and WFS services, they are often only configured to provide REST and SOAP services.

Raster arcgis "mapserver" layers

It is possible to connect to these layers in QGIS via the REST interface.
Firstly (and the most difficult part) you need to find the URL for the REST service for your layer. E.g. you might want to use a layer that is available in the ESRI "Maps for Personal Use" web map at: http://www.arcgis.com/home/webmap/viewer.html?useExisting=1
Hopefully with a little googling you will be able to find the address where you can browse the "ArcGIS services directory" of your favourite ArcGIS server. In this case it is: http://server.arcgisonline.com/ArcGIS/rest/services/

Find the layer that you want, copy the url for the REST service, and now you have at least two options:
1. In the QGIS Python console, run this:

qgis.utils.iface.addRasterLayer("http://server.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer?f=json&pretty=true","raster")

And you are done! Or,

2. Create a gdal service description file, e.g. by running this in a terminal:

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

You can now load this file into QGIS, e.g. by drag-and-drop.

Vector arcgis "mapserver" layers, "globeserver" layers and "featureserver" layers

It is not possible to establish a direct connection to an ArcGIS Server in QGIS for vectors layers. HOWEVER you can use the ogr2ogr utility provided in GDAL/OGR (v1.9 and up) which is standard in QGIS 2+ using the 'Protocol' Add Vector type to import E$RI ArcGIS Server formatted JSON response generated when you submit your request as a query. The ArcGIS Server must implement E$RI's Geoservices REST v1.0, however the vast majority will, as this interface is used by nearly all of their web mapping APIs.

Here is the process, which should work for both /MapServer/ and /FeatureServer/ alike:

Step 1
Find the ArcGIS "REST Services Directory" - 95% of the time this will look {website.domain}/ArcGIS/rest/services
  • TIP- try this using your favorite search engine: [search terms] +"/ArcGIS/rest/services" or if you know of a webmap that uses an ArcGIS Server, open the 'developer tool' in your web browser and review the html or 'network traffic' to find the url that the webmap is calling to for its data.

Here is an example: http://geodata.epa.gov/arcgis/rest/services/

Step 2
Navigate to the MapServer or FeatureServer your interested in (Service Directory -> Folder ->/ MapServer ->/ Layer). Note that you'll have to submit a separate command/query for each layer/objectid # on the MapServer...

Here is an example: http://geodata.epa.gov/arcgis/rest/services/OAR/USEPA_NEI_2005/MapServer/1/

Step 3
Add the following to the end of your URL:

query?where=objectid+%3D+objectid&outfields=*&f=json

So it should end up looking something like this:

http://geodata.epa.gov/arcgis/rest/services/OAR/USEPA_NEI_2005/MapServer/1/query?where=objectid+%3D+objectid&outfields=*&f=json

Step 4
4.A - Adding URL as a Vector File in QGIS
In QGIS use the 'Add Vector File' menu toggle to 'Protocol' and copy and paste the URL. Done - See notes below on Projections and conversion from here.

4.B - Alternative Method using GDAL/OGR from Command Line:
Open GDAL/OGR command line (NOTE- you may want to first copy and paste the GDAL folder or "ogr2org.exe" to a new folder where you'll want the data to save to). Windows users can use the OSGeo4w installer going to advance install and select all the GDAL commandlines and libraries to install into this new folder (make sure you're installing GDAL v1.9 or higher), linux users I won't have to tell you what to do, because your smart enough, Mac/OSX users as always your on your own :).

Copy and Paste the following into your favorite text editer, making sure you rename the filename (NOTE:No spaces in the filename) and URL:

ogr2ogr -f GeoJSON [FILENAME].json "[URL]" OGRGeoJSON

Review other operations for the command here: http://www.gdal.org/ogr2ogr.html

Should look something like this:

ogr2ogr -f GeoJSON OAR_USEPA_NEI_2005_(1).json "http://geodata.epa.gov/arcgis/rest/services/OAR/USEPA_NEI_2005/MapServer/1/query?where=objectid+%3D+objectid&outfields=*&f=json" OGRGeoJSON

Now all you need to change for each layer is the # for the objectid (in the case /1/) and the FILENAME.

  • This has worked for lines, polygons, points. I DID NOT test it on multi-geometry datasets that are sometimes used in ArcGIS Server layers
  • The commandline may give you an error that the CRS/Projection wasn't recognized, ignore this for the moment as long as the new file was created.

Open the newly created file as a GeoJSON vector or drag and drop this file into QGIS. The features may not appear at first, if you received the error that I mentioned above, you'll have to first manually set the CRS to the projection the server used, you should be able to find this as "Spatial Reference:" on the MapServer page in the ArcGIS Services Directory.

*Special Note - This will only query the first 1000 or sometimes 500 features. You can string multiple queries after this at 250 feature requests each by specficing the objectid # which is the uniqueid ArcGIS uses happily these are always whole numbers starting at 1 without gaps. To do this replace &objectid& with &objectid=1, 2, 3, 4, ...&. To find out how many features a particular feature contains you can replace &outfile...=json@ with count google ArcGIS REST Query for more types of requests the server can handle.

If someone is interested in developing a script/plugin for QGIS, please let me know