Saturday, January 29, 2011

Interactivity with FusionTableLayer and mouse clicks

The FusionTablesLayer in the Google Maps API is a bit of a black box. Fusion Tables generates a clickable tile overlay to use place in your Maps API application, but you don't get direct to change anything. If you want to change data, you have to do server side calls. However, the FusionTablesLayer does give you access to row data on click, which allows you to do interesting things server side.


In my sample interactiveftlayer, I use a Fusion Table of Google's corporate addresses. The table has a simple Color column, with values of 0 or 1. In the Fusion Tables map visualization for the table, I configured the Marker Icon such that values of 0 are green, and 1 are blue. The color means nothing of course about the actual office.


In interactiveftlayer, I suppress the InfoWindow by adding a suppressInfoWindows: true option to the layer initialization. I then add an event listener to the layer that captures the click event on the layer. This gives me row information about the feature clicked. I then send a XMLHttpRequest to the server (in this case App Engine) with the other color (1 if the color is 0, 0 if it is 1). After the response from the XMLHttpRequest, I reload the layer.


There's one tricky part, and hopefully we can find a way to improve this on the Maps API end. The FusionTableLayer is cached by the browser. Which means that even if the data has changed, the layer stays the same, at least at zoom levels visited while it was visible. This includes, BTW, not only the images but the row data associated with them. In order to defeat that caching, I append a Where parameter to the layer selecting for a Id greater than a random number from -1000 to 0. Since I know all Ids are greater than 0, I can do this. I'm not proud of that strategy, but it works.

Tuesday, January 25, 2011

Two Thumbed Closure Slider for Time Slider

I've posted a couple of times about sliders - Playing with Closure UI Library: Slider and a basic Basic Time Slider in Closure. My final slider example uses the same data set as the last, and incorporates a Two Thumb slider, meaning you can use the slider to set a range of values, not just a less-than or greater-than value. I also corrected something that impacted performance in the last sample, that is I checked whether the query changed by the different events, and change the query on the map layer when the query changes from the last. This is an artifact of the events that I'm listening form, MOUSEUP, MOUSEOUT, and KEYUP. You may remember in the first sample, I realized that firing off a query change whenever the slider had a CHANGE caused too many queries to hit the overlay server, causing the Map to show the missing overlay error. Listening for mouse and key events caused fewer events to fire, but still more than one per change. The change simply tests to see if the new query is different from the old query, and only re-query the layer server if the query changes.

Sunday, January 9, 2011

It's 2011: Time to think about the future of Geo

It's fairly traditional to start a year with either a retrospective of the previous year, or a look forward. Or, of course, both. In that tradition, I'd like to start the year thinking about some trends that I think are going to be important for Geo this year.

Powerful Easy Analysis Tools

This is the year. In 2005, the Google Maps API and Google Earth broadened the use of geography tools far beyond the traditional GIS crowd, sparking a debate between so-called neo- and paleo-geographers that lasted for years. In the last year or so that debate seems to have calmed down a bit, as traditional GIS tools adapted to the web, and neo-geographers, were everywhere. So there's room for a fresh controversy.

The Google Maps API, followed shortly by a host of other APIs from Yahoo!, Microsoft, OpenLayers and others, allowed developers to easily place maps on their site. But as I pointed out in my Ignite Spatial talk in September, developers and GIS professionals aren't the only ones who want to share spatial data. In fact, I'm guessing the vast majority of spatial data, by volume if not quality, is in tabular form. Geocommons has recognized this for years, providing easy tools for uploading, combining, and sharing spatial data. With the addition of Google Fusion Tables, and easy mapping of spreadsheets and sharing of data, powerful tools for data analysis are in the hands of anyone with a Google account. I won't call them "low-end" tools, though certainly they lack the power of ESRI's tools, or any of a host of other proprietary and open source GIS applications. I predict that this year will see a lot of people migrating to Fusion Tables, and others using the API to back-end store the data. Which leads us to

Cloud


OK, I almost had to slap myself for saying "Cloud." After all, of all the buzzwords going around, I think it is the least penetrable to people not "in-the-know" and perhaps has the most number of definitions. To make matters worse, Microsoft has diluted the term even more with this wacked commercial campaign.  However, it is being used a lot, so let me be clear, I think this is the year of Cloud Data Hosting.

I predict more and more spatial data will go into "The Cloud." We're already seeing that happening with services like SimpleGeo, Microsoft Azure's support for spatial data, and many other services. Fusion Tables of course has an API which I anticipate will be useful for a number of spatial data storage services.

Cloud Analysis


It's still early days on this. I think that 2011 will be the year of early adoption. In particular, tools like Google Earth Engine will allow you to run high-end analysis in cloud data centers. Some of these tools are already out there, but the introduction of Earth Engine allows you to do things we're used to in the spatial world, namely raster data analysis, but do it faster and cheaper than before.

Location


Well, really, who am I kidding? 2010 was the year of local and location. Facebook's Places and Places API were a very powerful entrance into the location and local scene. Google Places with Hotpot is a big entry into the local market, but it came pretty late in the year. 2010 was about local, 2011 local will become mainstream, such that everyone will have forgotten that it wasn't part of our sites. Remember when there weren't maps everywhere? That was only 6 years ago, now it's taken for granted. Local will get that way by 2012. When of course the world ends, right? That's what the movies tell us anyway.

Prediction posts are fun, because rarely are you held to them. But really they tell you more about where you are now. The things we can't talk about, or don't know about yet, those are the real surprises. Happy New Year everyone.

Saturday, December 18, 2010

Basic Time Slider in Closure

Earlier this month I was playing with a the Google Closure library and using the slider. I wanted to play with it for developing a time slider too. Since I'm going to History Hack Day at the end of January in London, I thought I'd show off some samples there and this was a perfect hack for that.

Anyway, it's pretty simple. You set minimum and maximum values on the slider that correspond to the millisecond values used by JavaScript to represent time. Then use the JS Date object to convert those to readable date and time for display under the slider. You can see the sample here. I set the slider to between Wed Dec 31 2003 23:59:59 and Fri Jan 01 2010 00:00:00 since I knew all dates in the underlying table fell between them. I used another Wikileaks table, the Afghan War Diary, 2004-2010 table.

The tricky part is that Fusion Tables doesn't document the date formats that it accepts for queries. We just haven't gotten around to changing the docs, but I happen to know that we accept these formats:

MM/dd/yy
MM-dd-yy
MMM-dd-yy
yyyy.MM.dd
dd-MMM-yy
MMM/yy
MMM yy
dd/MMM/yy
yyyy

Monday, December 13, 2010

AGU 2010: Data Visualization

So, this was the first year without a digital globes track. I think two things happened:


  1. Organizers got tired of doing it every year
  2. More important: Digital globes are now all over the American Geophysical Union's annual meeting. There's really no need to separately call it out.
So this year, I presented to Visualization Aided Data Analysis: Tools and Techniques for the Geophysical Sciences. Smaller than my other years at AGU, this was still a vital record of the different tools needed for data analysis. I was particularly impressed by Hank Childs' presentation on VisIt: A Tool for Visualizing and Analyzing Very Large Data, which really seemed to be a tool for visualizing anything in any possible way. Wow, awesome tool. I was also really impressed by Vis Research: Advances in Visualization Research by Ken Joy, U.C. Davis. He had really impressive visualizations of flow patterns.

My own discussions of Fusion Tables, Earth, and Earth Engine seemed a bit more basic, but perhaps that's the point I've been trying to make, that visualization tools can be powerful and hard to use, putting incredible versatility and detail in the hands or professionals, or easy to use and basic for everyone. And when they are easy and basic, everyone can use them effectively.
 Anyway, here's my slides:


Thursday, December 9, 2010

Freebase Meetup and JSONP

So, I was invited to speak at a Freebase meetup by Kirrily Roberts. I thought "Cool, Freebase. Oh, I should learn that!" Especially now that Freebase is part of Google! So apologies if you're looking for my intended next sample which was closure as a time slider, that will come.

I did a couple of maps mashups to try and learn the query language. But at the same time, I wanted to learn more about Google Closure. So, here's a couple of samples that I did. Let me explain in further detail:

<link href="http://code.google.com/apis/maps/documentation/javascript/examples/standard.css" rel="stylesheet" type="text/css" />
<script type="text/javascript" src="http://maps.google.com/maps/api/js?sensor=false"></script>
<script src="goog/base.js"></script>
<script>
   
goog.require('goog.net.Jsonp');
var obj;
var map;
 
function initialize() {
  var latlng = new google.maps.LatLng(0,0);
  var mapOptions = {
        zoom: 2,
        center: latlng,
        mapTypeId: google.maps.MapTypeId.ROADMAP
  };
 
 
  map = new google.maps.Map(document.getElementById("map_canvas"), mapOptions);
  getEvents(); 
} 

function getEvents() {
  var envelope = 'http://www.freebase.com/api/service/mqlread?query={%20%22query%22:%20[{%20
        %22type%22:%20%22/time/event%22,%20%22id%22:%20null,%20%22name%22:%20null,
        %20%22included_in_event%22:%20[{%20%22name%22:%20%22world%20war%20ii%22%20}],
        %20%22locations%22:%20[{%20%22geolocation%22:%20{%20%22latitude%22:%20null,
        %20%22longitude%22:%20null%20}%20}]%20}]%20}';
  getData(envelope,'');
} 

function getData(dataUrl,data) {
  var jsonp=new goog.net.Jsonp(dataUrl);
  jsonp.setRequestTimeout(100000);
  jsonp.send('',setObject);
}

function setObject(response){
  obj = response['result'];
  addMarkers();
}
function addMarkers(){
  for(var i in obj){
    for(var j in obj[i].locations){
      var latLng = new google.maps.LatLng(obj[i].locations[j].
            geolocation.latitude,obj[i].locations[j].geolocation.longitude);
      var marker = new google.maps.Marker({
          map: map,
          position: latLng,
          title: obj[i].name
      });}
      console.log(obj[i].name);
  }
}

So what I did there was use goog.net.jsonp from Closure to load the JSON from the query results and then create markers. The first sample finds events during World War II and find their geolocation. Since some events have more than one geolocation, it gives each location a marker with the same title, which will show up as a tool tip on hovering over the marker. In this case, the event contains a /location/location node which has /location/location/geolocation nodes. Someone comment if I'm not getting that quite right.

For those that don't know, I used the JSONP utility to get around the same domain policy of browsers, which prevents you from loading scripts directly from domains other than the one you are loading from. Server side scripting would have solved that issue for me easily, but I decided to set myself the additional challenge of finding that workaround. JSONP takes advantage of the caveat to the same domain policy that allows you to load scripts into <script> tags in HTML. In the case of the Closure library, it creates a temporary <script> tag, uses it to get the JSON object, and then gets rid of the script tag. One must exercise caution when using this approach, of course, that the source of your JSON is trusted to prevent attacks on visitors to your site.

My second sample took a /location/location, in this case Berkeley California (where I grew up) and found all /location/location nodes that had a containedby relationship to Berkeley California. And then mapped them. Then I added in animation to, so if you click on one place it bounces. Just for fun.

It was pretty basic. Figuring out the query language is not easy. Actually, before I spoke at the meetup, Jamie Taylor did a great talk about the schema which really cleared up some things for me. Unfortunately, we experienced a complete A/V failure in the room the meetup was in> Jaime did his talk with a white board, which I think made him happy. I jokingly referred to my talk as interpretive dance. I described my approach, why I was using JSONP, what tools were available, and then we went and had a beer.

Update

I should have credited this article on JQuery and JSONP with part of my inspiration.

Friday, December 3, 2010

Playing with Closure UI Library: Slider

For Google Developer Day in SaƵ Paulo, my colleague Ossama Alami created this sample, which allows you to select between three different Google Fusion Tables layers and play with queries against them. I looked at that and decided that I would use it to play with the Closure Library. Specifically, I wanted to play with the UI library. So for the GDD events in Munich, Moscow, and Prague, I decided to add a slider. The results were fun, and instructional for me. The code to add a slider was pretty simple. Here's my sample, and here's the slider code:


<script>

var el = document.getElementById('s1');
s = new goog.ui.Slider;
s.decorate(el);
s.addEventListener(goog.ui.Component.EventType.CHANGE, function() {
document.getElementById('out1').innerHTML = s.getValue();
});

goog.events.listen(
s.getContentElement(),
[goog.events.EventType.MOUSEOUT,
goog.events.EventType.KEYUP,
goog.events.EventType.MOUSEUP],
function() {
var preset = document.getElementById("preset").selectedIndex;
var query = presets[preset].sampleQuery + s.getValue();
document.getElementById('query').value = query;
layer.setTableId(parseInt(document.getElementById('preset').value));
layer.setQuery(query);
});
</script>


I just took that from the documentation. Of course, there's a an HTML element for the slider, and some CSS to style it, and loading the library itself. Well, you can view source. The instructional bit was that of course as soon as you move the slider, events start firing. If you listen for a CHANGE event, as you slide the slider, it'll fire too fast. Each tick, it'll try to grab a new layer from Fusion Tables. That'll consume lots of bandwidth as FT tries to return a layer with each tick. So instead, I listen for MOUSEOUT, KEYUP, and MOUSEUP events, which fire when the user is done moving the slider, either moving off it or releasing the mouse.

Next up, I'm going to try to use it to simulate a timeslider.

Sunday, November 21, 2010

Google Developer Days in Europe

I just got back from Google Developer Days in Munich, Moscow and Prague. OK, I got back on Thursday, but I'm just coming out of my jetlagged state. I presented similar talks in all three places, though in Munich I talked about Latitude, and in Prague Jarda Bengl joined me and talked about Street View. My demos are all linked in the slides. The theme was New Features in Google Geo. Here's the Munich slides:




Here's the Prague slides, with Street View at the end:



In Moscow, I went a little slower, cut out the Latitude and Street View slides because of the simultaneous translation. I did have a separate slide deck, but it adds nothing over the other ones.


Fusion Tables was the killer, though, very popular in all three cities, especially with the new spatial queries. Turns out, people love one click visualizations and easy Maps API integration. Especially fun was the demo I did using a Closure slider to dynamically change the FusionTableLayer query. I'm going to refine that some more, play with it and then do a write-up. I'm trying to take the time to learn Closure finally.


Finally, here's some pictures I took from GDD Moscow and the GTUG hackathon the next day. Unfortunately, people were pretty wiped by the next day, as there was a Android/HTML5 hackathon the day before. Some folks had traveled 16 hours on the train each way to go to GDD. Only about 20 people showed to the Geo hackathon the next day, but the energy level was great and people seemed to have a lot of fun.


MoscowGDDAndGTUG2010

Friday, October 15, 2010

Presentation at NACIS

I presented today at the North American Cartographic Information Society annual meeting, on new features in Google Earth Pro, Fusion Tables, and the Google Maps API. NACIS focuses a lot more on design, on cartography, and therefore it was a very interesting conference to be at, different from the usual GIS and developer conferences I present at. I sat in a session on rethinking the bike map afterward. Unfortunately, I had to leave after that, so didn't get to participate in much of the conference.

Here's my slides. There were a lot of questions on all aspects, but particularly on imagery.

Thursday, October 14, 2010

My Trip to University of North Texas

I had a great two days at the University of North Texas, organized by Andrew Torget, professor of History. I met with historians, engineers, folks from the College of Information, geographers, and more. Most of the meetings were unstructured, free form meetings. Those are sometimes the most fun. Today I did a presentation that was mostly demos from the new features in Google Earth Pro 5.2 and Google Fusion Tables. There was a lot of interest in the different features, and there's a link there in a getting start tutorial I threw together.


Plus I'm really starting to like goo.gl, especially now that it's open and you can track the click.