Wednesday, July 9, 2014

Putting your Professional Group on the Map

People love to know what’s happening in their area of expertise around the world. What better way to show it, than on a map? Tech Comm on a Map puts technical communication tidbits onto an interactive map, together with the data and functionality provided by Google Maps. 

I’m a technical writer at Google. In this post I share a project that uses the new Data layer in the Google Maps JavaScript API, with a Google Sheets spreadsheet as a data source and a location search provided by Google Places Autocomplete. 

Although this project is about technical communication, you can easily adapt it for other special interest groups too. The code is on GitHub.

The map in action 

Visit Tech Comm on a Map to see it in action. Here’s a screenshot:


The colored circles indicate the location of technical communication conferences, societies, groups and businesses. The “other” category is for bits and pieces that don’t fit into any of the categories. You can select and deselect the checkboxes at top left of the map, to choose the item types you’re interested in.  

When you hover over a circle, an info window pops up with information about the item you chose. If you click a circle, the map zooms in so that you can see where the event or group is located. You can also search for a specific location, to see what’s happening there. 

Let’s look at the building blocks of Tech Comm on a Map.

Getting hold of a map

I'm using the Google Maps JavaScript API to display and interact with a map.

Where does the data come from?

When planning this project, I decided I want technical communicators to be able to add data (conferences, groups, businesses, and so on) themselves, and the data must be immediately visible on the map. 

I needed a data entry and storage tool that provided a data entry UI, user management and authorization, so that I didn’t have to code all that myself. In addition, contributors shouldn’t need to learn a new UI or a new syntax in order to add data items to the map. I needed a data entry mechanism that is familiar to most people – a spreadsheet, for example. 

In an episode of Google Maps Developer Shortcuts, Paul Saxman shows how to pull data from Google Drive into your JavaScript app. That’s just what I needed. Here’s how it works.

The data for Tech Comm on a Map is in a Google Sheets spreadsheet. It looks something like this:



Also in the spreadsheet is a Google Apps Script that outputs the data in JSON format:

var SPREADSHEET_ID = '[MY-SPREADSHEET-ID]';
var SHEET_NAME = 'Data';
function doGet(request) {
 var callback = request.parameters.jsonp;
 var range = SpreadsheetApp
     .openById(SPREADSHEET_ID)
     .getSheetByName(SHEET_NAME)
     .getDataRange();
 var json = callback + '(' +
     Utilities.jsonStringify(range.getValues()) + ')';
 
 return ContentService
     .createTextOutput(json)
     .setMimeType(ContentService.MimeType.JAVASCRIPT);
}


Follow these steps to add the script to the spreadsheet and make it available as a web service:
  1. In Google Sheets, choose ‘Tools’ > ‘Script Editor’.
  2. Add a new script as a blank project.
  3. Insert the above code.
  4. Choose ‘File’ > ‘Manage Versions’, and name the latest version of the script.
  5. Choose ‘Publish’ >  ‘Deploy as web app’. Make it executable by ‘anyone, even anonymous’. Note: This means anyone will be able to access the data in this spreadsheet via a script.
  6. Choose ‘Deploy’.
  7. Copy the URL of the web service. You’ll need to paste it into the JavaScript on your web page.

In your JavaScript, define a variable to contain the URL of the Google Apps script, and add the JSONP callback parameter:
var DATA_SERVICE_URL =
  "https://script.google.com/macros/s/[MY-SCRIPT-ID]/exec?jsonp=?";

Then use jQuery’s Ajax function to fetch and process the rows of data from the spreadsheet. Each row contains the information for an item: type, item name, description, website, start and end dates, address, latitude and longitude.
$.ajax({
 url: DATA_SERVICE_URL,
 dataType: 'jsonp',
 success: function(data) {
   // Get the spreadsheet rows one by one.
   // First row contains headings, so start the index at 1 not 0.
   for (var i = 1; i < data.length; i++) {
     map.data.add({
       properties: {
         type: data[i][0],
         name: data[i][1],
         description: data[i][2],
         website: data[i][3],
         startdate: data[i][4],
         enddate: data[i][5],
         address: data[i][6]
       },
       geometry: {
         lat: data[i][7],
         lng: data[i][8]
       }
     });
   }
 }
});

The new Data layer in the Maps JavaScript API


Now that I could pull the tech comm information from the spreadsheet into my web page, I needed a way to visualize the data on the map. The new Data layer in the Google Maps JavaScript API is designed for just such a purpose. Notice the method map.data.add() in the above code. This is an instruction to add a feature in the Data layer. 

With the basic JavaScript API you can add separate objects to the map, such as a polygon, a marker, or a line. But by using the Data layer, you can define a collection of objects and then manipulate and style them as a group. (The Data layer is also designed to play well with GeoJSON, but we don’t need that aspect of it for this project.) 

The tech comm data is represented as a series of features in the Data layer, each with a set of properties (type, name, address, etc) and a geometry (latitude and longitude).

Style the markers on the map, with different colors depending on the data type (conference, society, group, etc):


function techCommItemStyle(feature) {

 var type = feature.getProperty('type');


 var style = {

   icon: {
     path: google.maps.SymbolPath.CIRCLE,
     fillOpacity: 1,
     strokeWeight: 3,
     scale: 10        
   },
   // Show the markers for this type if
   // the user has selected the corresponding checkbox.
   visible: (checkboxes[type] != false)
 };

 // Set the marker colour based on type of tech comm item.
 switch (type) {
   case 'Conference':
     style.icon.fillColor = '#c077f1';
     style.icon.strokeColor = '#a347e1';
     break;
   case 'Society':
     style.icon.fillColor = '#f6bb2e';
     style.icon.strokeColor = '#ee7b0c';
     break;

. . . SNIPPED SOME DATA TYPES FOR BREVITY

   default:
     style.icon.fillColor = '#017cff';
     style.icon.strokeColor = '#0000ff';
 }
 return style;
}

Set listeners to respond when the user hovers over or clicks a marker. For example, this listener opens an info window on hover, showing information about the relevant data item:
 map.data.addListener('mouseover', function(event) {
   createInfoWindow(event.feature);
   infoWindow.open(map);
 });

The Place Autocomplete search


The last piece of the puzzle is to let users search for a specific location on the map, so that they can zoom in and see the events in that location. The location search box on the map is provided by the Place Autocomplete widget from the Google Places API.

What’s next?


Tech Comm on a Map is an ongoing project. We technical communicators are using a map to document our presence in the world!

Would you like to contribute? The code is on GitHub.

Posted by Sarah Maddox, Google Developer Relations team.