« « Hope: Recognizing what you can and can’t change

How to make a non-Flash intensity map in Fusion Tables » »

How to combine multiple Fusion Tables into one map

Posted by on Aug 21, 2011 in Blog, Uncategorized | 14 Comments
I had the privilege of visiting Derek Willis’ Digital Frameworks class last week — a hallowed room that started my own data journalism journey. As most of you know, I’m unable to sit and merely observe (sorry, Derek!), so I ended up chiming in. One student explained that she was working on a Fusion Table project , but had too much data for one Fusion Table. She wished to split up the data, but have it all display on an integrated map.
This is possible, although you have to leave Fusion Tables’ point-and-click interface, and attack some actual JavaScript programming. I provide a basic template here with explanation, in hopes that it might help some folks. Here’s a link to what the final product should look like: http://michelleminkoff.com/multiple_fusion_tables_example.html
Before we start, please note that you should have your Fusion Tables ready to go. Each table has a URL, like “http://www.google.com/fusiontables/DataSource?dsrcid=1317738″. At the end of the URL, you’ll see an ID number after “dsrcid=”. You’ll want to keep that ID number for each of your table in an accessible place. Also, under the share option, all tables should be available to the public, so our computer program, as a member of the public can access these tables. Finally, all your tables should have similar infowindow (pop-up bubble) and style (colors/type of markers used), which you can set by visualizing data as “map”, and clicking the customize links. Finally, this tutorial will focus on displaying many points as a Fusion Table map. If you want to learn how to include an intensity and/or chloropleth map as one of these layers, I’ll have more on how to create that, and construct your own polygons, in a future post. Now that all that is out of the way…
1. First, we’re going to copy and paste this line in — it imports some of Google’s code that allows us to create a Google Map.
1
<script type="text/javascript" src="http://maps.googleapis.com/maps/api/js?sensor=false"></script>
2. We’re going to open up a new section of JavaScript in our file, with the first line. Lines 2-5 create a function we can use that creates a layer on a map. When this function is used, we will bring in a new layer, and the ID of a Fusion Table, we’re looking at putting in that particular layer. The line commented out with the slash should be included without the slash if you want infowindows to pop up, and if you don’t want them, either keep the line in with the slashes, or just delete it. The query looks at what we want to take from the table. My program here just selects everything from the table — if you know any Structured Query Language (SQL), the SELECT * FROM table formula should look familiar. Know that you can incorporate a WHERE statement, like in regular SQL, to only select rows that fit a certain qualification. For example, I’ve done apps that all fiti in a Fusion Table, but load smoother when a table is loaded into 4 different layers. That’s not what we’re after here, though.
1
2
3
4
5
6
7
8
<script type="text/javascript">
        function createFusionTableLayer(layer, table){
            layer = new google.maps.FusionTablesLayer(table, {
            //  suppressInfoWindows: true,
              query: "select " + "*" + " from " + table
            });
            return layer;
        }
3. Now, we’re going to set up a second function, that takes the layer we made, and sets it on a blank map. When we run these two functions multiple times, we’ll combine all our tables on that blank map.
1
2
3
4
5
6
 
        //Function initializes layers by putting them on map, 
        function setMap(layer){
            layer.setMap(map);
        }
</script>
4. But where is this blank map, Michelle? Well, here we are. You’ll open a new div, a content area used in HTML. Give it an ID, any ID you like, but make sure you remember this ID. Also, set an explicit height and width (and padding if you like), so the map knows what size you want it.
1
    <div id="gmap" style="width:750px; padding-top:40px;height: 700px;">
5. Now, we’ll put some JavaScript specific to this div or content area right here. We’ll set a blank map up, set the center as the center of the US, set the zoom to 4, which allows all of the US to fit on the map, but feel free to adjust as you wish. Tell the map you want it to display roads, although satellite and other options are available.
1
2
3
4
5
6
<script type="text/javascript">
	         map = new google.maps.Map(document.getElementById('gmap'), {
	                center: new google.maps.LatLng(39.0533, -95.6707),
	                zoom: 4,
	                mapTypeId: google.maps.MapTypeId.ROADMAP
	            });
6. Run through those two functions we made at the top, outside of the div, with as many layers as we have tables. Call the first one “layer0″, the next “layer1″, etc. Replace the numbers like “1318004″ with the table IDs I asked you to grab out of the table URLs at the beginning of this exercise. Then, close out our div, and that’s it! Copy and paste all this code into a blank HTML page or embed in your CMS. A little more involved than the usual way to make Fusion Table maps, but not *too* bad. Questions? I’m easy to find. Look out for a post soon on making polygon-based intensity maps that can be included as one of these layers, allowing you to overlay specific points on polygons.
One more point: Due to the way Google Maps works, when you click on one point and get an infowindow, and then click on another, the first AND second window will display. I like to deal with this by suppressing infowindows altogether, and bringing that information into a detail panel. But that requires some fancy footwork. I’m sure there’s a solution to this, but I’m still working on it at this point. I’ll let you know if I come up with something.
1
2
3
4
5
6
7
8
9
10
11
12
13
 
		var layer0 = createFusionTableLayer(layer0, 1318004);
                setMap(layer0);
 
                var layer1 = createFusionTableLayer(layer1, 1317738);
                setMap(layer1);
 
                var layer2 = createFusionTableLayer(layer2, 1325806);
                setMap(layer2);
 
                var layer3 = createFusionTableLayer(layer3, 1325564);
                setMap(layer3);
</script></div>
And here’s the whole chunk of code together for easy copy-and-pasting…
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
<script type="text/javascript" src="http://maps.googleapis.com/maps/api/js?sensor=false"></script>
<script type="text/javascript">  
 
       //Function creates layers that house various pieces of the map.  Split into parts because US is so big.
        function createFusionTableLayer(layer, table){
            layer = new google.maps.FusionTablesLayer(table, {
            //  suppressInfoWindows: true,
              query: "select " + "*" + " from " + table
            });
            return layer;
        }
 
        //Function initializes layers by putting them on map, 
        function setMap(layer){
            layer.setMap(map);
        }
</script>
 
 
    <div id="gmap" style="width:750px; padding-top:40px;height: 700px;">
 
		<script type="text/javascript">
	         map = new google.maps.Map(document.getElementById('gmap'), {
	                center: new google.maps.LatLng(39.0533, -95.6707),
	                zoom: 4,
	                mapTypeId: google.maps.MapTypeId.ROADMAP
	            });
 
		var layer0 = createFusionTableLayer(layer0, 1318004);
                setMap(layer0);
 
                var layer1 = createFusionTableLayer(layer1, 1317738);
                setMap(layer1);
 
                var layer2 = createFusionTableLayer(layer2, 1325806);
                setMap(layer2);
 
                var layer3 = createFusionTableLayer(layer3, 1325564);
                setMap(layer3);
		</script>
 
 
    </div>
« « Hope: Recognizing what you can and can’t change

How to make a non-Flash intensity map in Fusion Tables » »
  • Pingback: How to make a non-Flash intensity map in Fusion Tables « Michelle Minkoff

  • http://twitter.com/ChrisLKeller Chris Keller

    Great walk through Michelle… When you say “I like to deal with this by suppressing infowindows all together, and bringing that information into a detail panel” I think I had worked through the same question… 

    This might work for you – http://code.google.com/p/gmaps-samples/source/browse/trunk/fusiontables/change_infowindow_content.html?r=2544
    //click listener on layer google.maps.event.addListener(layer, ‘click’, function(e) { //writes data from layer to legend document.getElementById(‘map-legend’).innerHTML =  //search for FT column headings to display ” + e.row['County'].value + ” + ‘2007 Life Expectancy: ‘ + e.row['Male LE 2007'].value + ‘ Years’; 

    [Reply]

  • Chris K

    Well that code came through really bad….

    Here’s a link: http://chopapp.com/#dywesnlm

    [Reply]

  • Pingback: Combining Google Fusion Maps… | clairemiller.net

  • Kate Golden

    This is great – there are so few tutorials at this level. I just created one of these maps on my WordPress site using a couple of fusion tables — and they load up just fine together! that is cool.

    Unfortunately, the basemap gmap doesn’t load. Or rather it looks like it gets drawn but then disappears or is covered up (zooming in or out causes the basemap to flash visible for an instant). Any ideas on what the problem might be? Doesn’t look like WP is stripping the code (a frequent problem).

    The only thing I altered from the block above was the lat/long, the table IDs, and the maptype (I tried HYBRID and TERRAIN.

    Thanks!

    [Reply]

    Michelle Minkoff Reply:

    Kate: Hmmm….maybe this is your issue. (It’s hard for me to know for certain.)  If the content or “entry” area of your site’s theme in wordpress has a background-color, this could override the actual map, except for a brief second when the map redraws, like when you zoom.  You may have to change the CSS for the entry section of your WordPress site.  More here: http://stackoverflow.com/questions/8948864/fusiontableslayer-hides-the-underlying-map-on-a-wordpress-page

    [Reply]

    Kate Golden Reply:

    Ha ha! I posted that stackoverflow request (and then the comment after we figured it out). Good find, yes, that was indeed the problem. ;) Thanks again for the tutorial, Michelle.

    [Reply]

  • Pingback: Reading about Google Fusion Tables and More Advanced Mapping « Digital Mappings: Readings & Reflections

  • TCMcCarthy

    Michelle, 

    Thanks so much for the tutorial!

    After googling, adapting, adopting and massaging I think I have come up with a solution for the multiple info window issue. 

    What I have done is suppress the infoWindows that come preloaded in each layer as you have done and instead created a new infoWindow object the way you would with a regular google map. Then, to go along with it I have borrowed a function from another forum that allows a click listener to pass important data like infoWindow content, location, etc. and display the window how and where it’s supposed to be.

    /*–====================–*/

    Here is the function I borrowed:

    function windowControl(e, infoWindow, map) { //this allows for only one info window instance among several fusion tables layers
        infoWindow.setOptions({
            content: e.infoWindowHtml,
            position: e.latLng,
            pixelOffset: e.pixelOffset
        });
        infoWindow.open(map);
    }

    /*–====================–*/ 
    Here is the singular infoWindow object:

    var infoWindow = new google.maps.InfoWindow(); //the infowindow object to allow for layer info consolidation

    /*–====================–*/

    and here is the listener I attach to each of my fusionTables layers: 

    LISTENERNAME = google.maps.event.addListener(LAYERNAME, ‘click’, function(e) {          windowControl(e, infoWindow, map);        });

    These three steps worked very well for me … I am developing a template where multiple fusion tables can be layered on top of one another quickly by simply having the user fill out an array of encrypted tableIDs in a config file and/or database index entry. The template then loops through the array and automatically pulls in the layer info and bounds info so that the map will auto zoom/center and populate with data (and happily, styles).

    There are other features too, which are coming, but even something as simple as having a consolidated infoWindow had me scratching my head for a bit.

    Anyway, thanks for helping me get the wheel spinning!

    [Reply]

  • Tim Henderson

    This was helpful, thanks Michelle .. I was hoping I could throw in a search also that would drop a pin, then pop the infowindow on the appropriate polygon…surprisingly difficult! I would have to query the FusionTable for the polygon — more complex because now there are two possible tables to check — and then get all the information to reconstruct the infowindow from scratch. I decided to punt and just let it drop the pin and zoom way in, and have the user do the clicking. It would save a lot of headache if they would just let you fire the click event yourself in code — like “map.click(point)” — but no, that doesn’t seem possible.. But here it is in primitive but functional form
    http://data.lohud.com/maps/turnout.html

    [Reply]

    Michelle Minkoff Reply:

    Hear what you’re saying, but I think you made it work quite well with the restrictions you had to work with. Thanks for sharing!

    [Reply]

  • Pingback: (Spring 2012) Data Driven Interactive Journalism » Archive » Yellow Tag Sale: Best Buy to Close 50 Big Box Stores, Open 100 Mobile Phone Stores

  • Pingback: Mapping | Data Driven Journalism Fall 2013

  • Pingback: Mapping | Data Visualization -- Hickman