Google I/O 2009: Geo Round-Up

Wednesday, June 24, 2009

At Google I/O 2009, we had the opportunity to meet many of our favorite developers in the Sandbox and Office Hours, and deliver several advanced talks on geo topics. Check out the description of those sessions below (originally posted on the Google Code blog), or jump straight to the embedded player and watch them yourself.

Mano Marks and Pamela Fox started with a grab bag session covering the vast spectrum of Geo APIs, discussing touring and HTML 5 in KML, the Sketchup Ruby API (with an awesome physics demo), driving directions (did you know you can solve the Traveling Salesman Problem in Javascript?), desktop AIR applications, reverse geocoding, user location, and monetization using the Maps Ad Unit and GoogleBar. Pamela finished by sneak previewing an upcoming feature in the Flash API: 3d perspective view.

In the session on performance tips for Maps API mashups, Marcelo Camelo announced Google Maps API v3, a latency-oriented rewrite of our popular JS Maps API. Also see Susannah Raub's more in-depth talk about Maps API v3. Then Pamela gave advice on how to load many markers (by using a lightweight marker class, clustering, or rendering a clickable tile layer) and on how to load many polys (by using a lightweight poly class, simplifying, encoding, or rendering tiles). Sascha Aickin, an engineer at Redfin, showed how they were able to display 500 housing results on their real estate search site by creating the "SuperMarker" class.

Mano and Keith presented various ways of hosting geo data on Google infrastructure: Google Base API, Google App Engine, and the just-released Google Maps data API. Jeffrey Sambells showed how ConnectorLocal used the API (and their own custom PHP wrapper) for storing user data.

On the same day as announcing better integration between the Google Earth and Google Maps JS APIs, Roman Nurik presented on advanced Earth API topics, and released a utility library for making that advanced stuff simple.




Travellr: Behind the Scenes of our Region-Based Clusters

Monday, June 22, 2009

Recently, there has been a lot of interest in clustering algorithms. The client-side grid-based MarkerClusterer was released in the open source library this year, and various server-side algorithms were discussed in the Performance Tips I/O talk. We've invited the Travellr development team to give us insight on their unique regional clustering technique.

Travellr is a location aware answers service where people can ask travel-related questions about anywhere in the world. One of its features is a map-based interface to questions on the site using Google Maps.



Figure 1. An example of the Travellr Map, showing question markers for Australia.


Clustering for usability

We learned that the best way to display markers without cluttering our map was to cluster our questions depending on how far you zoom in. If the user was looking at a map of the continents, we would cluster our questions into a marker for each continent. If the user zoomed-in to France we would then cluster our questions into a marker for each region or city that had questions. By clustering our data into cities, regions/states, countries, and continents, we could display relevant markers on the map depending on what zoom level the user was looking at.


Optimizing for Clustering

Our next challenge was how to extract clustered data from our database without causing excessive server load. Every time the user pans and zooms on the map, we need to query and fetch new clustered data in order to display the markers on the map. We also might have to limit the data if the user has selected a tag, as we're only interested in a questions related to a topic (ie: "surfing"). To execute this in real-time would be painstakingly slow, as you would need to to cluster thousands of questions in thousands of locations with hundreds of tags on the fly. The answer? Pre-cluster your data of course!


Step 1. Structure your location data

When a question is asked about a city on Travellr, we also know its region/state, country and continent. We store more than 55,000 location points as a hierarchy, with each location "owning" its descendent nodes (and all of their data). Our locations are stored in a Modified Preorder Tree (also called Nested Sets). Modified Preorder Trees are a popular method of storing hierarchical data in a flat database table, having a focus on efficient data retrieval, and easy handling of sub trees. For each location we also keep a record of its depth within the tree, its location type (continent, country, region/state, or city), and its co-ordinates (retrieved using the Google Maps geocoder).


Step 2. Aggregate your data

We calculate aggregate data for every branch of our locations tree ahead of time. By storing aggregate data for cities, regions/states, countries, and continents, we provide an extremely fast and inexpensive method to query our locations database for any information regarding questions asked about a particular location. This data is updated every few minutes by a server-side task.

Our aggregations include:

  • Total question count for a location
  • Most popular tags for that location
  • Number of questions associated with each of those tags.

How we query our structured, aggregate data on the map

Whenever the user zooms or pans the map we fire off a query to our (unpublished ;) API with the tags they are searching for, the current zoom level, and the edge co-ordinates of the map's bounding box. Based on the zoom level (Figure 2) we work out whether we want to display markers for continents, countries, states, or cities. We then send back the data for these markers and display them on the map.



Figure 2. Clustering at different zoom levels (blue = continents, countries, pink = states, cities)


Everyone Wins

So what is the result of structuring and aggregating our data in such a way? It means that we have nicely organized, pre-clustered data that can be read from cheaply and easily. This allows us to provide a super-fast map interface for Travellr that puts minimal load on our infrastructure. Everyone is happy!

Comments or Questions?

We'd love to hear from you if you have any questions on how we did things, or suggestions or comments about Travellr's map. This article was written by Travellr's performance and scalability expert Michael Shaw (from Insight4) and our client-side scripting aficionado Jaidev Soin.

You can visit Travellr at www.travellr.com, or follow us on Twitter at twitter.com/travellr.

How low can you go? Introducing getMaxZoomAtLatLng

Tuesday, June 16, 2009

When you're showing satellite imagery with our Maps API, it's often the case that you want to show the most detailed imagery available. But it's always been tricky figuring out the best zoom level for a particular location. If you don't zoom in far enough, your users won't immediately get the most detailed image available. If you zoom in too far, you might get the dreaded message "We are sorry, but we don't have imagery at this zoom level for this region", and no imagery at all.

What if there were a way to know programatically what the maximum zoom level was for any point in the world? Fortunately, now there is.

It's not easy to solve this problem naively; the world is a big place. At zoom level 22, there are 4 to the power of 22 potential satellite tiles -that's over 17.5 trillion. The zoom level for satellite imagery that exists varies wildly all over the world. Sydney's Bondi Beach has imagery right up to zoom level 22, whereas the centre of the Pacific Ocean only goes up to zoom level 9. (I make no accusations about whether this means the Google Maps team prefers to look at tanned, sunbathing Aussies).

But with a good search algorithm, and data based on the most frequently viewed areas of the earth, we've been able to make a search for the existence of imagery very efficient, and we are now exposing this functionality to our API developers.

The new solution is an asynchronous function which is part of the GMapType class: getMaxZoomAtLatLng. The function takes a GLatLng and returns the maximum zoom level at which imagery exists. Because the function requires a call to Google's servers (much like GClientGeocoder.getLocations()), you must also provide a callback parameter, which is a function which will deal with the response.

As an example, here's a function which will set the center of the given GMap2 object to the maximum zoom level at the given GLatLng:

 
function setMaxZoomCenter(map, latlng) {
  map.getCurrentMapType().getMaxZoomAtLatLng(latlng, function(response) {
    if (response && response['status'] == G_GEO_SUCCESS) {
      map.setCenter(latlng, response['zoom']);
    }
  });
}

As you can see, the response object contains a status code, and, if the response was successful, a zoom field containing the maximum zoom at that point.

Click on the map below, and it will zoom to the highest zoom level available at the point at which you clicked.

Note that this function is only implemented for satellite imagery, and not roadmaps, whose zoom levels don't vary nearly as much. It works for both the G_SATELLITE_MAP and G_HYBRID_MAP map types. The full reference is available here.

We hope this function makes developing with satellite imagery a simpler, easier and fuller experience. Please provide any feedback in the Maps API Google Group.

Announcing the Google Qualified JS Maps Developer program

Friday, June 05, 2009

Labels:

Developer Qualification

Last week at Google I/O we released the Google Maps API (JavaScript version) addition to the Developer Qualification program. Designed for professionals who currently develop or want to develop applications based on Google and Google-sponsored Open Source APIs, the Google Qualified Developer program will help promote developers to the Google community, provide credibility, and leverage the wisdom of the masses in rating and recognizing best in class developers. In this program, we assess developers in four areas, each of which provides a score towards an overall total required for qualification. Developers must maintain a minimum number of points to remain qualified within the program. Points are awarded for examples of development work, community participation, professional references, and scores on examinations.

With the addition of the Google Maps API to the available qualifications, the program landing pages and registration have been moved to the Google Code site at http://code.google.com/qualify. The new landing pages provide information on the program and available APIs, details about qualification requirements, answers to frequently asked questions, and an opportunity to apply as a candidate in the qualification program.

We've also recently partnered with 3rd party training vendors who can help you get ready to qualify. The Developer Qualification program provides a mechanism by which Google can evaluate and promote the best developers in the community, but does not provide training in preparation for qualification. With the success of the program there exists a business opportunity for 3rd party training vendors to develop and deliver this training. In order to stimulate the growth of this ecosystem, several vendors have been identified and are working closely with Google to develop initial training efforts for the Google Maps API qualification.

To read more about the program, take a look at our site. We look forward to expanding our API support and growing the Developer Qualification program. Please reach out to us with questions and feedback at devqual-proctors@google.com.

Hey Maps API and Earth API developers, we just beefed up G_SATELLITE_3D_MAP!

Friday, May 29, 2009

Labels: ,

When the Earth API launched back in May 2008, there was a simultaneous addition to the Maps API that allowed creating an 'Earth' map type with just a single line of code:

map.addMapType(G_SATELLITE_3D_MAP);
Figure 1: Old version

This was really the first time that the 2D world of Google Maps and the 3D world of Google Earth came together. Users could navigate content publishers' geographic content in 2D or 3D, whichever they desired.

However, there were a few limitations with G_SATELLITE_3D_MAP. For example, only Maps markers and polylines were synchronized in 2D and 3D. Other overlay types were not kept in sync. Also, the transition from 2D and 3D wasn't as transparent to the user as it could've been. See Figure 1 to the right for an artist's depiction of the feature set.

Today, we're excited to announce a completely rewritten and 'beefed up' G_SATELLITE_3D_MAP (see Figure 2), available now in the latest experimental version of the Maps API (currently 2.160). While the usage is the same (simply use the line of code above), the overlay/feature synchronization is much more extensive, the 2D/3D transitioning is seamless, and the overall Maps/Earth integration is much stronger.

Most common Maps API overlays are now supported: markers, polylines, polygons, ground overlays, screen overlays, and even GGeoXml objects are automatically mirrored in the Google Earth Plugin. In fact, GGeoXml works in an especially powerful way: although Maps may not display all KML from a GGeoXml (i.e. 3D models), the Earth Plugin will show all the content, in all its 3D glory.

If you're as psyched as I am about the new features and want to give them a go, check out these demos and the short screencast below:

To enable the new Maps/Earth integration on your site, simply load the experimental Maps API version using:

google.load('maps', '2.160');

and add the G_SATELLITE_3D_MAP map type. When Maps API v2.160 or later becomes version '2', the new Maps/Earth integration will replace the old version, which will then only be available by hard coding to version 2.159 or earlier in the google.load statement.

Lastly, if you have any trouble with the new integration code, please post in the Maps API or Earth API developer forums. Also see the Earth API notify group announcement for more details on this release.

Announcing Google Maps API v3

Wednesday, May 27, 2009

Since our last major release of the JavaScript Maps API three years ago we've been delivering feature requests that all of you have been asking for month over month. With over 150,000 active websites implementing it, the Maps API has become one of the most popular and trusted developer tools on the web. We're in the process of giving the Maps API a major facelift and today we're providing you a look at V3 in our Google Code Labs.

The primary motivation behind this new version was speed, especially for rendering maps on mobile browsers. Last year, several of us starting thinking about the possibility of getting the JavaScript Maps API to work on mobile devices. With the advent of powerful, fully functional browsers on devices such as the iPhone and the Android-based G1, why couldn't we bring the flexibility and reach of modern web development to people who wanted to write maps mashups for mobile phones? While we've been able to get the existing v2 API working on mobile browsers, we found we were constrained when trying to reduce latency and we needed a new approach. And thus was born the idea for the next revision of the Maps API.

We wanted to get this in your hands as soon as possible, so we've intentionally released it early, and with a basic set of features. We're releasing it in Labs because it's not fully baked yet; we want to get your feedback on the new design and what you'd like to see in future revisions now that we have a chance for a fresh start. Yes, this does mean that you'll have to rewrite your existing mashup code if you want to take advantage of v3, but we think that speed is very important to a great user experience.

What's changed in v3? Besides the substantial improvements in speed, a few other things that you'll notice in the initial release:

  • iPhone Safari mobile and Chrome added to our supported browsers. Your mashups will also work on Android-based phones with the recent update, but you may notice some issues, like the "View/Save Image" dialog showing unexpectedly. We're working with the Android team to fix this and improve the end user's experience in interacting with the map. We could've waited until it's perfect, but we really wanted to get an early release in your hands and start getting feedback while we fix up a few remaining issues.
  • No keys required. You can now copy 'n paste code easily or embed in RSS readers, for example, without getting key errors.
  • MVC-based architecture. This allowed us to significantly reduce the size of our initial JavaScript download. We found it to be simple and powerful.
  • Default UI is enabled automatically. We'll provide default UI controls and behavior (and we'll update them) so your mashup can keep up with the latest and greatest changes we make to Google Maps. Of course, if you've got customized controls you're happy with, you can disable the default UI updates.
  • Namespaces. Everything is always in the google.maps.* namespace and there is no "G" prefixed variables in the global scope.
  • Geocoding API has been overhauled based on the feedback we've received with the existing implementation over the past three years.
Check out the reference and documentation for more details.

What does the API look like? Here's a quick, complete example that you can grab to render a map. It's even set up to render a full-screen interactive map on the iPhone and Android browsers.


<html>
<head>
<meta name="viewport" content="initial-scale=1.0, user-scalable=no">
<script type="text/javascript" src="http://maps.google.com/maps/api/js?sensor=false"></script>
<script type="text/javascript">
  function initialize() {
    var latlng = new google.maps.LatLng(-34.397, 150.644);
    var myOptions = {
      zoom: 8,
      center: latlng,
      mapTypeId: google.maps.MapTypeId.ROADMAP
    };
    var map = new google.maps.Map(document.getElementById("map_canvas"), myOptions);
  }
</script>
</head>
<body onload="initialize()">
 <div id="map_canvas" style="width:100%; height:100%">
</body>
</html>

We've set up a new group for you to provide feedback. Also, the terms have been updated to remind you that versions we release as "experimental" or in Labs may not have the same level of support as ones that are already out of Labs. This means that we'll continue to support the current v2 API well after v3 matures and graduates from Labs. In the meantime, we're looking forward to adding a lot more functionality to this new release so please send us your feedback!

Introducing the Google Maps Data API in Labs

Wednesday, May 20, 2009

Labels: , ,

From simple GPS tracks to rich KML documents to collaborative maps, the geo developer community has continually redefined and enriched the geoweb, giving rise to better canvases for geographic participatory culture. Notably, the Google Maps API and other tools have led to the creation of more dynamic and interactive content, putting new demands on the ways in which geodata is stored, accessed, indexed and rendered. To address these challenges, today we've released the Google Maps Data API in Labs, a Google Data API for viewing, storing and updating geodata on the web. The Google Maps Data API is built on the following principles:

  • Storage should scale simply with usage. You shouldn't have to worry about maintaining a data store to build a cool Google Maps mashup. Focus on building the client, and we'll provide hosting and bandwidth for free.
  • Geodata should be accessible across platforms and devices. With many client libraries and clients, accessing stored geodata should be possible from anywhere, whether it's on the web, a mobile phone, a 3D application, or even a command line.
  • Realtime geodata requires realtime indexing. For a lot of geographic content, freshness is important. Geodata from the Google Maps Data API can be instantly indexed and made searchable in Google Maps.
  • Rendering geodata is better and faster with the right tools. Through JavaScript, Flash, 3D, static images and more, we'll continue to provide better ways to render your content to meet platform and latency demands.
Much like KML, the Google Maps Data API is based on a data model of maps (collections) and features (placemarks, lines and shapes). Since it uses this familiar model, this new API makes it easy to build geo applications for specific activities like planning and sharing trips, collaboratively mapping hiking trails, or saving a list of favorite restaurants. Also, for any map that is associated with a Google Account, that map is immediately available to view and edit in Google My Maps. Some examples of applications which already use the Google Maps Data API:
  • My Maps Editor for Android allows users to create and edit personalized maps from an Android mobile phone. Integration with the phone's location and camera makes it easy to document a trip with photos and text on a map.
  • ConnectorLocal is a service that informs users about the places where they live, work and visit by gathering trusted hyperlocal information from many sources. Using the Google Maps Data API, ConnectorLocal makes it easy for users to import and export their geodata in and out of Google Maps, and also improves their ability to have data indexed in Google Maps for searching.
  • My Tracks enables Android mobile phone users to record GPS tracks and view live statistics while jogging, biking, or participating in other outdoor activities. Stored with Google Maps Data API, these tracks can be accessed, edited and shared using the My Maps feature in Google Maps.
  • Platial, a social mapping service for people and places, uses the Google Maps API to host geodata for community maps on both Platial and Frappr.
If you're a developer, we encourage you to get started with the Google Maps Data API immediately with our HTTP protocol guide. Additionally, the team at We-Create (the company behind ConnectorLocal) has released their Webready library for PHP developers, built on top of the Zend Framework. Of course, this release in Labs is only the beginning -- in the future, we'll continue to add new functions and libraries to make the API even better. In the meantime, we hope you'll get an early start in developing new applications and pushing the boundaries of the API. Be sure to stop by our group to ask questions, give us feedback, and let us know what you've made!