National Map in GovCMS

NationalMap is the perfect tool for displaying geographical data from a range of Australian government agencies, and now with the NationalMap Component in Convivial we can augment geo data from additional data sources to see data in a new light.

19 March 2019

NationalMap is an intuitive interface that allows you to explore and filter a vast collection of geographic data. Convivial is a distribution that extends GovCMS with a NationalMap Component. In this article we will walkthrough embedding a national map without a single line of code, and show you how we built it.

National Map Embed
A map displaying geo data via 3 different methods (Custom GeoJSON, URL and Share URL)

NationalMap Component

In Convivial we have created a "NationalMap" paragraph which allows you to augment geo data from multiple data sources onto the one map. Geo data can be sourced from nationalmap.gov.au, data.gov.au or by pasting in custom geo data.

An example entry of GeoJSON data looks like:

National Map Catalog Item

In this example we've referenced GeoJSON via a URL. GeoJSON is a great format for storing spacial data as it's easy to author, read and consume by National Map. Geo data can either be referenced via URL, pasted directly into the Data field, or by referencing the "Share URL" provided by NationalMap when adding data via its UI.

Once you've added a few entries, simple save the form and the resulting page will show a National Map of all your geo data.

Nomenclature

NationalMap introduces the concept of Catalogs and Catalog Items, which we adhere to closely.

Catalog

National Map Catalog

A catalog can be thought of as a layer except it contains multiple catalog items within it, each with their own data source. A catalog has 2 important properties:

  • Name - What will be displayed in the sidebar for the "layer"
  • Open - Whether the layer's geo data should be hidden or seen on the map

Catalog Item

A catalog can have many catalog items, but usually will have just one. The catalog item is where the magic happens and has a few key properties:

  • name - In most cases will match the name of the catalog
  • type - Data type such as "geojson" or "csv"
  • url - URL to the geo data of the same data type specified by "Type"
  • zoom - The map will zoom in to the bounding box around the data with this option checked

Our Technical Implementation

The software behind NationalMap is called Terria.js, and is open source. We can embed a national map and populate it with geo data via its API. Our implementation is as follows:

Step 1 - Process geo data

From the user supplied form data we generate JSON suitable for consumption by Terria.js/NationalMap. In GovCMS it is not possible to add new code via custom modules, however it's possible to add server side logic via the theme layer. We can use the template_preprocess_paragraph() hook to generate JSON for consumption by the front end.

In the template_preprocess_paragraph() hook we check that the entity type is a paragraph and that the entity bundle is a national_map. We then generate an array of catalog data. The last but most important part is to pass that data to the client side with:

$vars['#attached']['drupalSettings']['national_map'][$id] = [
  'id' => $id,
  'catalogs' => $catalogs,
];

Now the JSON can be accessed on the client side via drupalSettings.national_map with a Drupal behaviour.

Step 2 - Embed map

Embed NationalMap via an iframe:

<iframe id="map" src="https://nationalmap.gov.au" width="100%" height="500px"></iframe>

Step 3 - Wait for map to load

Get the iframe and wait for it to load via Javascript:

// Wait for message event.
window.addEventListener('message', function(event) {
  // Get iframe's content window.
  var iframe = $('iframe#map').get(0).contentWindow;
  // When iframe has loaded.
  if (event.source === iframe && event.data === 'ready') {
    // Step 3...
  }
}

Step 4 - Render geo data

The iframe was introduced in 1997. HTML has come a long way since then and now lets us communicate through the iframe to the embedded website via HTML5's postMessage method:

// Ask iframe to render catalogs.
iframe.postMessage({
  initSources: [{
    catalog: []
  }]
}, 'https://nationalmap.gov.au');

The catalog property takes an array of catalog objects. An example data set looks like this:

[{
  type: "group",
  name: "Ballarat Recreation",
  items: [{
      type: "geojson",
      name: "Ballarat Bike Racks",
      url: "https://data.gov.au/dataset/a75255ab-6a92-4a82-9fdd-dc87b1dce993/resource/9cc717db-1378-4e91-95f3-b39e55b3069d/download/ballaratbikeracks.geojson",
      zoomOnEnable: false
    },
    {
      type: "geojson",
      name: "Ballarat BBQ's",
      url: "https://data.gov.au/dataset/f2ab58d7-18b7-44dc-9121-9cd0ae829d22/resource/b0480515-e45e-419e-a1a6-9a1f862a8751/download/ballaratbbqs.geojson",
      zoomOnEnable: true
    }
  ]
}]

The NationalMap Component generates all of this HTML and JSON for you, so you don't have to play around with JSON data structures each time you'd like to embed a national map.

 

Summary

Convivial's NationalMap Component lets you embed a NationalMap using data from a variety of sources anywhere on a page in a straight forward manner.

An example of the NationalMap embed can be seen on the Convivial Demo page.