Discovery - A QGIS Gazetteer

The Discovery plugin adds search capability to QGIS. Its key features are:

  • Connects directly to PostgreSQL / PostGIS (no reliance on web services)
  • Auto-completion of results
  • Flexible expression-based support for scales
  • Can use multiple fields to display result context
  • Simple GUI-based configuration

We'd like to thank Tim Martin of Ordnance Survey for his original PostGIS Search plugin which gave us inspiration and formed the foundation of Discovery.


Discovery can be found in the official QGIS plugin repository. To install Discovery in in QGIS, simply select Plugins > Manage and Install Plugins... from the main menu. The Plugin Manager dialog will appear. In its left-hand panel, select Get more. Within the Search box now type discovery. Select the Discovery plugin from the list and click Install plugin.

The Discovery toolbar should now be visible in QGIS:

Discovery Gazetteer Plugin GUI

Configuring Discovery

Click the Configure Discovery button, Discovery Gazetteer Plugin GUI, to open the Discovery settings dialog.

Discovery Gazetteer Plugin Settings

The following sections describe the various settings.

Connection - The existing PostGIS connection to use.

Schema - The database schema holding the table.

Table - The table containing the location / gazetteer data.

Search Column - The column in the above table which will be searched for terms entered by the user.

Display Columns - Optional existing columns used to provide context for auto-completed search results. For example, we could point these settings to columns describing the feature type and county which would yield a result like: Newcastle, City, Tyne and Wear

Geometry Column - The column containing geometry describing the location of the result.

Scale Expression - An optional QGIS expression used to define a scale at which to display the result. The expression should return a scale denominator (e.g. 10000). For example, the following expression would display populated places at a scale of 1:300000 and everything else (e.g. postcodes) at a scale of 1:3000 based on the content of the TYPE column:

CASE WHEN TYPE = 'populatedPlace' THEN 300000 ELSE 3000 END

BBOX Expression - An optional QGIS expression used to define a bounding box in which to display the result. The expression should return a bounding box in the form 'xmin,ymin,xmax,ymax'. If present, Discovery will use the bounding box expression in preference to the scale expression. If the bounding box expression does not give a valid output, the scale expression is used instead.

The following expression could be used to build bounding boxes for results of type 'transportNetwork' based on the values in the MBR_XMIN, MBR_YMIN, MBR_XMAX and MBR_YMAX columns:

CASE WHEN "TYPE" = 'transportNetwork' THEN MBR_XMIN || ',' || MBR_YMIN || ',' || MBR_XMAX || ',' || MBR_YMAX END

Windows users' Discovery settings are stored in the Windows registry. In the case of a large QGIS deployment, these registry settings can be packaged with QGIS to 'pre-configure' users' installations.

Using Discovery

To use Discovery, simply type into the text field on the toolbar. Results will be autocompleted. Results will be displayed on result selection.

The point location of the result will be displayed for a short time as a red marker.

Discovery Gazetteer Plugin In Action

Tips for Best Performance

Discovery will convert user input into a SQL query similarly to this:

  • User input: tower bridge
  • SQL query: SELECT ... FROM ... WHERE name ILIKE '%tower%bridge%'

You'll notice that the search is case-insensitive and uses search wildcards. This type of search can be slow if the searched column is not indexed.

We therefore recommend using a tasty gin index based on the pg_trgm PostgreSQL extension. This can be achieved using the SQL query below. Either run the query in pgAdminIII or pass it to your database admin and ask them to make it so.

-- Create the pg_trgm extension on the database CREATE EXTENSION IF NOT EXISTS pg_trgm; -- Create an index on the NAME1 column of the -- open_names table in the gazetteer schema CREATE INDEX open_names_name1_gin_trgm ON gazetteer.open_names USING gin ("NAME1" gin_trgm_ops);