Skip to main content

Official websites use .gov
A .gov website belongs to an official government organization in the United States.

Secure .gov websites use HTTPS
A lock ( ) or https:// means you’ve safely connected to the .gov website. Share sensitive information only on official, secure websites.

    Join us to learn about upcoming changes to water data APIs in a public webinar designed for all interested users of USGS Water Data APIs, including USGS cooperators, partners, and the general public on Thursday May 29th at 12pm ET / 11am CT / 10am MT / 9am PT. Link to the event.

Accessing USGS water data with QGIS

The USGS Water Data APIs implement the OGC API - Features standard in order to increase the interoperability of USGS water data with other tools and data sources. One example of this interoperability is that it's possible to query and download USGS water data from most GIS systems, which frequently support reading directly from OGC API - Features APIs and adding their data to maps.

This tutorial walks through the specific steps required to access USGS water data within QGIS, a popular open source GIS tool. It assumes you already have QGIS installed and are familiar with how to navigate and symbolize data. More information about QGIS can be found in the QGIS user manual.

Connecting to Water Data APIs from QGIS

The first thing we need to do is configure the Water Data API server as a "WFS / OGC API - Features Layer" provider in QGIS.

In a new project, we'll open the the "Layer" menu, navigate to the "Add Layer" submenu, and then click on the "WFS / OGC API - Features Layer" item:

Image of the "Layer" drop down menu in QGIS. The "Add Layer" submenu has been expanded and the "Add WFS / OGC API - Features" option is highlighted.

This will open up a window that we can use to add a new server connection:

Image of the "Data Source Manager" window in QGIS. No sources are configured, and the window is broadly blank.

Click the "New" button under "Server Connections" to open another window, which will let us define our connection:

Image of the "Connection Details" window in QGIS. The information specified below has been filled out.

In this window, we need to fill out a few key pieces of information:

Once we provide those, we can close this window with "OK" and then press "Connect" under "Server Connections" to see the data collections available from the Water Data API server:

Image of the "Data Source Manager" window in QGIS. This time, the Water Data APIs server has been added as a source, and three collections - "Daily values", "Monitoring locations", and "Time series metadata" - are displayed.

Querying the time series metadata collection

We're now able to access data from any of these collections in QGIS. Because these are large data sets, it's important that we filter our downloads to just the data that we're interested in; otherwise, we might freeze QGIS by trying to download too much data, or get rate limited by making too many requests to the APIs.

Say, for instance, we wanted to get a map of all the time series which measured discharge in the last six months. We can do this by clicking on the "time-series-metadata" endpoint in the list, then clicking the "Build Query" button.

This will open a new window that lists the different fields we're able to query on. In the "Provider Specific Filter Expression" box, we'll write out the query that we want to run out against our APIs:

"parameter_code" = '00060' AND "end" = 'P6M'

This query will let us find all time series measuring discharge ("parameter_code = 00060") which have been active in the last 6 months ("end = P6M", meaning that the most recent data from this timeseries is in the past "Period of 6 Months").

Image of the "Query Builder" window in QGIS. The filter expression window contains '"parameter_code" = "00060" AND "end" = "P6M"'

Hit "OK" to close the query builder window and on the Data Source Manager window, click "Add" to load the data to a new layer on the map. This will display point data for recent discharge measurements. Click "Close" on the Data Source Manager window.

A map of time series meeting the earlier filter, globally. Most points are concentrated in a polygon resembling the continental United States.

For display purposes, we're going to change the coordinate reference system of our map to use the EPSG:5070 coordinate reference system for the rest of this tutorial. We're also going to zoom into the continental United States to make individual time series more evident:

A map of time series meeting the earlier filter across the continental United States. Thousands of grey dots suggest the outline of the lower 48 states.

In addition to location information, the points on this map include the full set of data associated with each observation. We can see these values by opening the Attributes table by right clicking the layer's name in the Layers window, or by highlighting a single point with the Identify Features tool.

The attributes table for the filtered time series is open over the same map as in the last image. To the right, a sidebar lists the attributes of a single selected point in the map, which is highlighted in red.

You can export this data using the "Save Features As" menu, accessed by right-clicking the layer name in the layer viewer:

An image of the menu opened by right clicking on a layer in QGIS. The "Export" menu is expanded, with the "Save Features As" option highlighted.

If you want to edit the query a layer is using, right click on the layer's name in the Layers window and click "Filter" to return to the Build Query menu.

Querying the daily values collection

If we want to add a different layer to our map -- for instance, if we wanted to view daily values -- we first need to reopen the Connections menu, going through the "Layer" menu into the "Add Layer" submenu and then clicking the "WFS / OGC API - Features Layer" item.

We might need to "Connect" to the Water Data APIs server again, but we shouldn't need to re-define our connection. By clicking on the "Daily" collection and then clicking the "Build Query" button, we can then start building a query against the daily values endpoint. Because this endpoint contains a large amount of data, it's important that we filter down to just the data that we're interested in, which we'll do using the query:

"time" = 'P1D' AND "parameter_code" = '00060' AND "statistic_id" = '00003'

This query will filter our results down to just the mean ("statistic_id = 00003") discharge ("parameter_code = 00060") daily values from the past day ("time = P1D" -- that code meaning that we want data from "a Period of 1 Day"):

'The Query Builder window in QGIS. The filter expression this time is "time" = "P1D" AND "parameter_code" = "00060" AND "statistic_id" = "00003".

One thing to note is that these APIs store most numbers, including daily values, as string objects to preserve significant figures and avoid issues with rounding on different computers. As such, if you want to symbolize your map based on these numbers, you'll first need to create a virtual field that converts the string into a decimal value.

From the attributes table of the layer, we'll open the Field Calculator menu:

An image of the attributes table for the filtered daily values. The "Field Calculator" button is highlighted.

In this menu, we create a virtual field with the "Decimal (double)" type. Our expression to create this field is just the name of the field we want to convert. In this example, because we're going to symbolize our map based on the "value" field, we'll input "value" in the "Expression" box:

The field calculator menu, showing an output field name of "value_numeric", an output field type of "Decimal (double)", and an expression of "value".

We can then use our virtual field to symbolize the data. Once the field is created, close the attribute table, right-click on the Daily values layer and go to Properties. It should default to the Symbology tab, but if it doesn't, it's the third option down on the left. Change from the default "Single Symbol" to "Graduated." Change the value to the newly created "value_numeric" field. Using the default settings, click "Classify" to auto-generate 5 classes in Equal Count (Quantile) mode. We'll also change the color ramp used to the "Blues" ramp instead.

The symbology menu in QGIS. A graduated symbology is selected, based on the "value_numeric" field, using the default Blues color ramp, and classified.

This process then lets us symbolize our maps using numeric fields as we'd expect:

A map in shades of blue of discharge daily values across the continental United States.

These tools should allow you to query and visualize any data provided by the USGS OGC API - Features endpoints. More information about the data available from each endpoint can be found on the endpoint schema pages; for example, this page lists the data returned by the daily values endpoint, while the time series metadata endpoint is documented here.