JavaScript and Flash are great for putting Google Maps on your website, but sometimes they just won't do. For mobile browsers or users with dial-up connections, simpler is better. So I wrote an open source non-JavaScript version of Google Maps which is designed to show how easy it is to write an application on App Engine that makes use of two new APIs from Google: The Static Maps API and the Local Search API's REST interface. It doesn't have advanced features like street view and public transportation, but it gives you a searchable map that you can zoom in/out on as well as save locations. It also automatically saves your last map view so that every time you go back to the site it will show you what you were last looking at. Check out the source code.

It uses App Engine to store saved points, the AJAX LocalSearch REST API for search functionality, and the Static Maps API to display maps. App Engine is easy to learn and the data store is useful for this kind of application. The REST API for LocalSearch is also very simple. For more information on it, go here.

To use the Static Maps API, you just need to create a URL with the proper parameters for your desired map view. Keep in mind that you need to set the zoom level (unless you are specifying multiple points — then it's calculated for you). In the vast majority of cases, this is completely fine. In my case, though, I needed to know what the zoom level was, so that I could give the user the option to zoom in/out. That meant coming up with calculations of the zoom both for the multiple points and single point case, and that was the trickiest part of the app.

If you use the AJAX Local Search and it returns one result then there will be a viewport object returned with it. This viewport contains the Northeast and Southwest latitude/longitude bounds that are optimal for displaying this point. However, Static Maps only accept zoom levels and center points. Here's the Python to generate that information:

viewport = json['responseData']['viewport'] mercator_projection = MercatorProjection(18) # Checkout the MercatorProjection class southwest = [float(viewport['sw']['lat']),float(viewport['sw']['lng'])] northeast = [float(viewport['ne']['lat']),float(viewport['ne']['lng'])] bounds = [southwest, northeast] zoom_level = mercator_projection.CalculateBoundsZoomLevel(bounds, MAP_SIZE)

At this point you will have everything you need to construct the map: the center point (the Local Search point), zoom level, marker point.

Then there's the case where you have multiple points returned by the AJAX Local Search. Since we will have a collection of latitudes and longitude points that we want to display we can just find the min/maxes, do some rounding, and voilà you get a bounding box. With a bounding box and a calculated center point, you can repeat the same steps as before.

mercator_projection = MercatorProjection(18) bounds = CalcBoundsFromPoints(lats, lngs) center_point = CalcCenterFromBounds(bounds) zoom_level = mercator_projection.CalculateBoundsZoomLevel(bounds, MAP_SIZE)

From line 121 to about 285 you'll find all the necessary functions for the situations described above. Try using this code to create your own interactive version of Static Maps, and let us know in the forum if you have questions or just want to show off your nifty app.