Mapping with Google Fusion Tables

Earlier this year I created a lab assignment for Sally Hermansen’s Advanced Cartography course at the University of British Columbia. The purpose of this lab was to introduce students to Google Maps and managing data in Google Fusion Tables. I’m posting it here in case anyone else finds it useful. I’d also like to thank Sally’s TA Sam Walker for his help testing this assignment. For that course I also created a short QuantumGIS tutorial, which I will post separately: A Very Short Introduction to QGIS.


Geographical Biogeosciences 472
Advanced Cartography
Lab 2: Google Maps

The objective of the lab is to create an interactive, web-based map that would be suitable for inclusion on the web edition of a major newspaper or in a blog post by an advocacy organization. In this lab you will have to consider the differences between static paper maps and dynamic web maps. You will also confront the challenge of making a map using nothing but free tools, skills which will be useful to you when you have graduated and no longer have access to a lab with ArcGIS installed. You will also be learning more about Open Source GIS software and Volunteered Geographic Information (VGI) in the second to last week of the course.

In this lab you will use a variety of free mapping tools built on Google Maps. You will use Google Fusion Tables to manage and map your data, and you will learn how to use the Google Maps API to customize the appearance of the basemap.

The point layer you create will be clickable, using pop-up boxes to provide the map reader with additional information such as statistical information, photographs, or links to web pages.
For demonstration purposes, each step of this lab will be explained using city population data from Statistics Canada. You are welcome to use this data while you work through the lab and learn the techniques. However, you must select a different point data set for the final map that you will turn in. Do not turn in your assignment using the same city population data used as the example in this lab.

Part 1: Getting Started

1.1: Overview of web mapping

A web map consists of three main parts: the basemap, the content layers, and the web page that holds the map together.

The basemap is a raster image composed of pre-generated static “tiles”. The basemap is usually a general-purpose road map or a satellite image. On top of the basemap, a web map can overlay one or more layers of content. Frequently this content is point data, but it can also include lines and polygons, as well as raster overlays. The basemap and the content layers are combined in an HTML web page (usually with the help of some JavaScript code) and dynamically displayed in the end user’s web browser. The web page can be thought of as the frame that holds the map together.

In some cases all three parts are hosted on the same web site (for example, on Google’s servers). However, it is also possible that the frame, the basemap, and the content layers are all sourced from different data providers across the web. In this lab we will mainly use Google products, but we will experience some of the various possibilities in how a web map can be assembled.

Google provides several different ways to make maps. Here are a few of them:

  • Custom Maps (formerly called “My Maps”) is the simplest way to add points, lines, and polygons to a map. These features must be created and edited manually; there is no way to import data into a Custom Map. Also, Custom Maps are limited to a fixed set of symbols and must use one of Google’s default basemaps (roads, satellite, or terrain). The map content and the basemap are all hosted on Google’s servers. We will not use Custom Maps in this lab. To read more about Custom Maps: http://support.google.com/maps/bin/answer.py?answer=62843
  • The Google Maps API (Application Programming Interface) lets you add maps to your own web page and control their appearance. Using the API requires a some knowledge of HTML and JavaScript code. In part 3 and 4 of this lab we will be seeing HTML code and JavaScript code mixed together.
  • Fusion Tables are the newest method for mapping data on Google Maps. A Fusion Table is an online database similar to a spreadsheet. In part 2 we will load data into a Fusion Table and use the built-in tools to visualize the data on a map. In part 3 we will combine our Fusion Table and the API, using Fusion Tables to manage our data, but using the API to control the appearance of the map, and host it on our own web page. For this lab then, we will be using Fusion Tables with the Google Maps API.

In addition to Google Maps, there are several other for-profit and Open Source alternatives – Some software alternatives include: Bing Maps API, MapQuest API, OpenLayers, and Leaflet. Other sources of data include OpenStreetMap and GeoCommons, to name a few.

1.2: Setup

For this lab you will need to create a Google account if you do not already have one: http://accounts.google.com

Next, you will need to create an API key here: https://code.google.com/apis/console/

Switch the “Google Maps API v3″ status from OFF to ON. Then, in the left hand bar, select “API Access”. Ignore the messages about creating an OAuth client ID, that is only necessary if you intend to solicit information from the users of your map. Note the API key, a long string of letters and numbers. Copy this key somewhere; we will use it later.

Part 2: Fusion Tables

2.1: Data processing

Collect a dataset of point data that you wish to map. The data must have at least one column that can be geocoded: this could be a city name, a postal code, or a full street address. You do not need to find data that already contains geographic coordinates such as a shapefile. Your data can be at any scale, from street addresses within one city up to the locations of several cities across multiple countries. You may use data for anywhere in the world, although Google’s geocoding may not be very successful if you plan to use street addresses in countries outside of North America or Europe. Your dataset should have more than 20 points, although larger numbers (100 or more) are preferred.

For the examples given in the lab we will download the recently-released “Population and dwelling counts, for census metropolitan areas and census agglomerations, 2011 and 2006 censuses” table from Statistics Canada: http://www12.statcan.gc.ca/census-recensement/2011/dp-pd/hlt-fst/pd-pl/Table-Tableau.cfm?LANG=Eng&T=201&S=3&O=D&RPP=150

Load your data into an Excel spreadsheet, if it isn’t in one already. Remove any columns (or rows) that you do not want on your map.

We will upload our Excel file from the page http://docs.google.com/. Click the red “create” button and select “Table (beta)” from the drop down options. In the next window, choose to import a file from your computer. Select the .xls file from your computer when prompted. Next you will be prompted which columns you want to import. Remember that all of the fields in this spreadsheet will be visible to anyone who has the link, so if any of the columns contain private information, do not include them. Then, in the final window, you will be prompted to change the table’s name and to add some metadata. It is not necessary to “allow export” at this stage.

2.2: Geocoding and visualizing the data

When the import is complete, you should see your data displayed in a new Fusion Table. The import process may have already recognized which column contains your geographic data. These will be highlighted in yellow. If the import did not detect which column contains your locations, go to Edit > Modify Columns and make sure that one of your columns is set to have the “Location” type. (You will see this as the second entry under Column Details.)

Select File > Geocode to save the geocoding results. If the geocode window seems to be stuck on 0%, make sure you press “start”. You can tell an address has been geocoded by mousing over each address and seeing the Google Earth icon appear (a small blue globe). Fields that have not yet been geocoded or where the geocoding failed will be shown in yellow.

More information about geocoding in Fusion Tables: http://support.google.com/fusiontables/bin/answer.py?answer=1012281

Now select Visualize > Map to view the result of the geocoding. Look for any dots that seem out of place. If there are any problems, return to table view (click Visualize > Table) to edit the geocoded field and re-geocode. You can update the geocoding for a row by clicking the Google Earth icon next to the location name.

In map view, you will see several links right above the mapped area. Let’s look at these one by one.

  • Click “Configure info window”. A new window will appear titled “Configure info window contents”. Here you can modify the window that pops up when a user clicks on a map feature. Check or uncheck the fields that you want to be visible. Optional: if you know HTML, you can click “Custom” and have more control over the style of the info window. When you are done configuring the info window, click save.
  • Click “Configure styles”. A new window will appear titled “Configure map styles”. Here you can change the symbology of your map if you like. Note, however, that we will override this symbology using the API in part 3.
  • Notice the link to “export as KML”, which would let you view the table in Google Earth. This link will not be active if your table is not set to be “exportable”. You can make your table exportable by choosing File > About and clicking “Edit table information”
  • Also notice the link to “get embeddable link”. This is a quick way to embed the map in a web page, although it is less powerful than the API technique we will use later. The embeddable link does not give us the ability to add multiple content layers or control the appearance of the background layer.

Click the “Share” button in the upper right corner of the window. My default your table will be set to “private”, but we have to make the table “public” or “unlisted” if we want to view the data using the Google Maps API (in the next section). Again, remember that all the fields in your table will be visible in table view, even if they aren’t visible in the map view.

Finally, view File > About, and make a note of the table’s Numeric ID. We will use this ID in the next step.

Part 3: Google Maps API

3.1: Creating a web page

First we will be creating an html page which will be the container for our map. HTML is the computer language (or “code”) that determines the content of a web page and what that page looks like. When you type in a web address (a Universal Resource Locator or URL) into a web browser such as Firefox, the browser downloads the HTML code and converts it into the web page you see on the screen.

Use a text editor or word processor program such as Notepad++ (Wordpad or Word will work if Notepad is not available) or a specialized HTML editing program like Dreamweaver, if you are comfortable using it.

Create a file index.html in your H: drive, in the “www” folder. If you are using Word, make sure you save the file as “Plain Text” type, not as a Word document. However, it must have the “.html” extension, not “.txt”.

Paste code: be careful to type in all the names and punctuation exactly as shown. Computer code is very sensitive to the smallest errors, so leaving out a comma or a semicolon could cause the entire page to malfunction (usually without explaining why).

<!DOCTYPE html>
<html>
<head>
<title>
Google Fusion Tables map
</title>
<script type="text/javascript" 
   src="http://maps.googleapis.com/maps/api/js?key=AIzaSyCEuqZ2P33bGHhqxdbnze6ShIw4zx8Qk_Y&sensor=false">
</script>
<script type="text/javascript"> 
   function initialize() { 
      var latlng = new google.maps.LatLng(55, -95); 
      var myOptions = { 
         zoom: 4, 
         center: latlng, 
         mapTypeId: google.maps.MapTypeId.ROADMAP 
      }; 
      var map = new google.maps.Map(document.getElementById("map_canvas"), myOptions); 
   } 
</script> 
</head> 
<body onload="initialize()"> 
   <!-- Add your own text between these comments --> 
    Hello world! 
   <!-- Add your own text above --> 
   <div id="map_canvas" style="width:800px; height:500px"></div> 
</body> 
</html>

You do not need to understand everything that is happening in the HTML and JavaScript.

Any text between <!-- and --> is called a “comment”. (Note that the string of characters that begin a comment include an exclamation point, but the closing characters do not. This is not a typo!) Anything written between these symbols will be ignored by the computer. Comments are a good way to leave notes for yourself or for other people who might need to view or edit your HTML code. These comments will not be visible when your web page is viewed in a web browser. For this lab you must use comments in your code to explain what you are doing. Your final mark will depend, in part, on the readability of your code.

You should modify this code in three places (in bold above). First, edit the title of the page (between the <title> and </title> tags). You can call the page whatever you like. Second, edit the API key, replacing it with the key that you created in part 1.2. Third, edit the text of the web page, replacing “Hello world!” with whatever you like. You may also need to modify the starting latitude and longitude in the google.maps.LatLng() statement, if you need to center your map on an area other than Canada. This will depend on what data you choose to map. In the example above, we specify the center of the map is “55, -95”. (In other words, 55º N, 95º W, which works well for a map of Canada). You can also change the scale of your map by changing the number after the “zoom:” statement. Higher numbers make the map more zoomed in. A zoom levels of zero results in a world map, while a zoom level of 16 is approximately neighborhood scale. You can use trial and error to determine the best zoom level for your map.

Note that everything within the <script> tags is the Google Maps code. In subsequent steps we will add more code to these sections. To learn more about how the API works, here is a general overview from Google: http://code.google.com/apis/maps/documentation/javascript/tutorial.html

Now let’s try viewing this page. Type in the URL: http://www.geog.ubc.ca/~username/ , replacing username with your own account name. (Note: the tilde character ~ is important!)

You should see your web page containing a blank Google map, along with the “Hello world!” text that you modified.

3.2: Adding a fusion table

Now we will add your fusion table to this map.

Here is some specific information about adding Fusion Tables to your map using the API: http://code.google.com/apis/maps/documentation/javascript/layers.html

After the line var map = new google.maps.Map(document.getElementById("map_canvas"), myOptions);insert the following code:

      var layer;     
      var tableid = 12345;     
      layer = new google.maps.FusionTablesLayer({       
         query: {         
            select: 'Name',         
            from: tableid       
         },     
      });     
      layer.setMap(map);

Replace the tableid with the id of your fusion table (which you recorded at the end of Part 2). In the select line replace ‘Name’ with the name of the column in your fusion table which contains your geocoded locations.

Save the HTML file. Then try viewing the page in your browser again. The features from your Fusion Table should appear on the map.

3.3: Styling the fusion table map

Next we will add a style to your fusion table. Here are some details about styling your Fusion Tables (we will be styling via the Google Maps API, not the Fusion Tables API): http://code.google.com/apis/fusiontables/docs/articles/fusiontables_styling.html

Again, after the line var map = new google.maps.Map(document.getElementById("map_canvas"), myOptions); insert the following code:

      var fusion_styles = [        
         {          
            markerOptions: {           
               iconName: "small_blue"         
            }       
         }, {          
            where: "Population > 200000",
            markerOptions: {
               iconName: "small_green"
            }
         }, { 
            where: "Population > 1000000",
            markerOptions: {
               iconName: "small_red"
            }
         }
      ];

Then, after the from: tableid }, lines, add this line:

      styles: fusion_styles

The first few lines define the default style for your points. The subsequent statements override any previous styles. In this case, all cities will have the “small_blue” marker applied, but those with populations over 200000 will be overridden with the “small_green” marker. Similarly, any of those with population over 1000000 get “small_red”.

Now, modify the statements to match your own dataset.

This example page illustrates the available icon options for the iconName field: http://www.google.com/fusiontables/DataSource?snapid=S363311tnv8

Part 4: Changing the basemap style

4.1: Using the Styled Map Wizard

When using the Google Maps API you have the ability to modify the appearance of the basemap. Here is overview of changing the basemap style: http://code.google.com/apis/maps/documentation/javascript/styling.html

We will use an online tool called the Styled Map Wizard to design our custom style, then paste the javascript code into our web page. The Styled Map Wizard: http://gmaps-samples-v3.googlecode.com/svn/trunk/styledmaps/wizard/index.html

Open the Styled Map Wizard and zoom in on the map until you see a lot of detail: the extent of downtown Vancouver, for example.

At the left, in the “Selectors” window, choose a category of feature type, for example, Road > Local. Check the “Visibility” styler below to activate it, then select “Off”. Notice how the local roads have disappeared from the map. When the local roads style is how you want it, click the “Add” button in the “Map Style” window on the right.

Then, in the “Selectors” window, select “All” for your feature type. For “Element type” select “Labels”. Then under “Stylers” turn the visibility off. Notice how the labels for all features have disappeared. Save this as part of your style by clicking “Add” in the “Map Style” window.

When you are finished styling your map, click “Show JSON” at the bottom of the “Map Style” window. JSON stands for “JavaScript Object Notation”, which is how we will add the style information to the JavaScript code embedded in our web page.

Your JSON code might look something like this:

   [  
      { 
        featureType: "landscape.man_made", 
        stylers: [ { visibility: "off" } ] 
      },
      { 
        featureType: "road.local", 
        stylers: [ { visibility: "off" } ] 
      },
      { 
        featureType: "road.arterial", 
        elementType: "labels", 
        stylers: [ { visibility: "off" } ] 
      },
      { 
        featureType: "road.highway", 
        elementType: "labels", 
        stylers: [ { visibility: "off" } ] 
      },
      { 
        elementType: "labels", 
        stylers: [ { visibility: "off" } ] 
      },
      {
        featureType: "landscape.natural",
        stylers: [ { hue: "#eeffee" } ]
      },
      {
        featureType: "poi.park",
        stylers: [ { hue: "#eeffee" } ]
      }
   ]

4.2: Adding the custom style to our map

In your HTML file, after the function initialize() { line, add the following line:

var style = [

Then paste in your JSON code, except for the first and last square bracket. Following the JSON code, paste the following four lines:

    ];
    var styledMapType = new google.maps.StyledMapType(style, {
      name: 'Custom Style'
    });

Then, find the line mapTypeId: google.maps.MapTypeId.ROADMAP and replace it with these lines:

   mapTypeControlOptions: {
      mapTypeIds: [google.maps.MapTypeId.ROADMAP, 'custom-style']
   }

Finally, following the line that begins var map =, paste these lines:

   map.mapTypes.set('custom-style', styledMapType);
   map.setMapTypeId('custom-style');

Your final HTML file should look something like this:

<!DOCTYPE html>
<html>
<head>
<title>Google Fusion Tables map</title>
<script type="text/javascript"
   src="http://maps.googleapis.com/maps/api/js?key=AIzaSyCEuqZ2P33bGHhqxdbnze6ShIw4zx8Qk_Y&sensor=false">
</script>
<script type="text/javascript">
   function initialize() {
      var style = [
         {
            featureType: "landscape.man_made",
            stylers: [ { visibility: "off" } ]
         },
         {
            featureType: "road.local",
            stylers: [ { visibility: "off" } ]
         },
         {
            featureType: "road.arterial",
            elementType: "labels",
            stylers: [ { visibility: "off" } ]
         },
         {
            featureType: "road.highway",
            elementType: "labels",
            stylers: [ { visibility: "off" } ]
         },
         {
            elementType: "labels",
            stylers: [ { visibility: "off" } ]
         },
         {
            featureType: "landscape.natural",
            stylers: [ { hue: "#eeffee" } ]
         },
         {
            featureType: "poi.park",
            stylers: [ { hue: "#eeffee" } ]
         }
      ];

   var styledMapType = new google.maps.StyledMapType(style, {
      name: 'Custom Style'
   });

   var latlng = new google.maps.LatLng(55, -95);

   var myOptions = {
      zoom: 4,
      center: latlng,
      mapTypeControlOptions: {
         mapTypeIds: [google.maps.MapTypeId.ROADMAP, 'custom-style']
      }
   };
   var map = new google.maps.Map(document.getElementById("map_canvas"), myOptions);

   map.mapTypes.set('custom-style', styledMapType);
   map.setMapTypeId('custom-style');

   var fusion_styles = [
      {
         markerOptions: {
            iconName: "small_blue"
         }
      }, {
         where: "Population > 200000",
         markerOptions: {
            iconName: "small_green"
         }
      }, {
         where: "Population > 1000000",
         markerOptions: {
            iconName: "small_red"
         }
      }
   ];

   var layer;
   var tableid = 2883162;
   layer = new google.maps.FusionTablesLayer({
      query: {
         select: 'Name',
         from: tableid
      },
      styles: fusion_styles
   });
   layer.setMap(map);
}

</script>
</head>
<body onload="initialize()">
   <!-- Add your own text between these comments -->
   Hello world!
   <!-- Add your own text above -->
   <div id="map_canvas" style="width:800px; height:500px"></div>
</body>
</html>

Click here to view a live example.

Part 5: Hand in the following on a few typed pages:

  1. The link to the web page you created that contains your Google Map. You do not need to hand in a printout of the map or of your HTML code; the TA can view the source code of your web page from the web browser.
  2. The link to view your fusion table. (When viewing your table, click Get Link in the upper left corner to get this URL). You do not need to hand in a printout of your data.
  3. A short written response that answers the following questions:
  • What is the purpose of the map, and who is your imagined audience?
  • How did you select and process your data? Were you able to find the data you wanted?
  • How did you decide on the final cartographic styling of your map? What challenges did you encounter using the Google tools? Were there any things you wanted to do, but couldn’t?
  • Compare the process of making a Google Map with the process you went through in lab 1. What are the strengths and weaknesses of each approach? When might you choose to make a map using traditional GIS and design tools (as in lab 1) and when might you choose to use Google tools?

Your written response will be worth 30% of your lab grade. Your map (including the supporting web page and the underlying data) will be worth 70%. Your web page will be marked on the following criteria:

  • Appearance. Are the content layer(s) symbolized in a logical and effective manner? Has the basemap been modified in a way that supports the map’s theme? Does the map load at an appropriate level of zoom, and is it centred on the correct area? (30%)
  • Functionality. Does the map respond to the map reader’s interaction? Are the map features clickable and do they display useful information (such as links, images, and/or additional Fusion Table fields)? Are the pop-up boxes well-designed? (10%)
  • Data. Is the data appropriate, and has it been processed and formatted correctly? (10%)
  • Integration between the map and the rest of the web page. Does the map support the message communicated by the images, text, and links on the rest of the page? Does the rest of the page sufficiently explain what the map reader should learn from the map? (10%)
  • Cleanliness and readability of your HTML code. Your HTML does not need to be significantly different from the example given above, but all the changes you make should be logical and well-formatted. (10%)
This entry was posted in Mapping, not_geowebchat. Bookmark the permalink. Post a comment or leave a trackback: Trackback URL.

One Trackback

  • [...] the results of which are posted to the course tumblr. This assignment was inspired in part by Alan McConchie’s Fusion Tables assignment. Whereas McConchie focuses in part upon utilizing Fusion Tables capacity to geocode a table, our [...]

Post a Comment

Your email is never published nor shared. Required fields are marked *

*
*


4 + = thirteen

You may use these HTML tags and attributes <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>