Software Secret Weapons™

 
Java Script Framework For Building Google Maps In Minutes
by Pavel Simakov on 2007-05-07 16:14:04 under AJAX, view comments
Bookmark and Share
 

The Google Maps API has been available for free, public-facing sites since February 2005. A remarkable variety of sites (over 30,000 in number) have already integrated Google’s mapping technology using this API. New sites are being built every day.

I have been doing Google Maps on and off from the very beginning. Over time it became clear to me that from the intergration perspective the Google Maps applications should be cost-effective to build, quick to deploy and easy to maintain for both simple websites and complex web applications. While pursuing these goals, I became aware several of important aspects of dealing with Google Maps:

  • There are many good Google Maps tutorials out there; my favorite tutorial is one by Mike Williams

  • Geocoding is great, but some manual work will always be needed; we had to correct spelling errors in addresses and massage addresses a bit before they get properly coded

  • Adding markers to Google Maps is slow (specifically on IE) if you want to place over 100 markers on the map at the same time; this is easily resolved by using elabel.js JavaScript library that is much more lightweight and can handle many more markers; even when using elabel.js avoid adding GEvent to each marker at all costs

  • When using AJAX to bring the map data from the server don’t use XML as data format – use JSON objects as described previously; the JSON objects are hundred times faster and less CPU intensive

  • Make sure that you know JavaScript very well; all over the place Google Maps API uses closures and lambda functions; the structured error/exception handling is not there – if you do something wrong all you will ever get is "Object blah is null"; all Google's own code is obfuscated so you can't understand anything in there; you also have to know how prototype-based inheritance works in JavaScript

  • Obfuscate your JavaScript; the obfuscation is a snap using modified version of Rhino JavaScript engine called Dojo's Compressor, which is a part of Dojo Toolkit; it handles most of JavaScript correctly except for some forms of eval(); this code below will not work after it is obfuscated:


function foo(msg){
	alert(msg);
}

function do(){
	var msg = "Here we go!";
	eval("fo" + "o(msg);");
}

do();

While learning in depth about the Google Maps, I have created several rather complex working map applications. You can view them here:

The examples show the basics of working with Google Maps, but this is not the most intersting thing about them. These examples are built using custom JavaScript application framework. In this framework, the metadata is used to define the filters on the right-hand-side and a table at the bottom of the page. The main metadata file is called manifest.js and it defines all the information about the map. Here is an example of the JavaScript metadata required to configure the Timothy’s Coffee page:


//
//  These are the generic framework objects 
//


// zone represents one page with map, filters, and table
function oygZone(width, name, desc, url, columns, 
	rowBuilder, popupBuilder, iconChooser, filtersCaption, filters){ ...}

// column is a column in the data table
function oygColumn(propName, caption, isNum, isSelector, align){ ... }

// all kinds of filters are here
function oygDropDownActionList(caption, lambdas, captions, selIndex){ ... }
function oygOneOfOrAllDropDownFilter(caption, lambdas, captions, selIndex){ ... }
function oygCheckboxFilter(caption, propLambda, checked){ ... }
function oygSubStringFilter(caption, propLambda){ ... }

// spacer without text
function oygStaticSpacer(){ ...}

// old static text
function oygStaticText(caption, align, clazz){ ... }


//
// These are the resources used by the Timothy’s Coffee
//

var columns = [
	new oygColumn("wf", "Wireless Internet", false, false, "center"),
	new oygColumn("sadd", "Address", false, true, "left")
]; 


function iconChooser(item){
	return "<img border='0' src='/bin/fwk/img/pal1/gmarker.gif'>";
}


function rowBuilder(item){
	var check = "<img src='/bin/fwk/img/pal1/check.gif'>";

	var addNoCou = item.add;
	var idx = addNoCou.indexOf(", Canada"); 
	if (idx != -1){
		addNoCou = addNoCou.substr(0, idx);
	}

	return [
		item.wf ? check : "",
		addNoCou
	];
}
 
function popupBuilder(item){ 
	var bull = "• ";

	var buf = 
		"<div class='oyg-info'>" +
		"<b>Timothy's World Coffee</b><br />" +
		item.add + "<br />" +
		"Phone: " + item.pho + "<br /><br />" +
		(item.wf ? bull + "<b>Wireless Internet / Hot Spot</b>" : "") + 
		"</div>";  
  
	return buf;
}

var filters = [
	new oygStaticSpacer(), 
	new oygSubStringFilter("Address Contains", function(row){ return row.add; }),
	new oygStaticText("for example: 'M2M' or 'Yonge'", "center"), 	

 	new oygStaticSpacer(),
	new oygCheckboxFilter(
		"Wireless Internet", function(row, checked){ return !checked || row.wf; }, 
		false
	),
	 
	new oygStaticSpacer() 
];

var oygZones = [
	new oygZone(
		748, "Timothy's World Coffee", "<b>Timothy's World Coffee</b> (Fall 2006)", "json/20060826/web.js", 
		columns, rowBuilder, popupBuilder, iconChooser,
		"Find Timothy's Near You", filters
	)
];

The raw map data is loaded from JSON objects. The JSON objects can have any number of attributes. These attributes in the implementation of the filters and the rowBuilder() and the popupBuilder() callback functions. Here is a part of the complete data file for Timothy’s Coffee page:

"oygMarkers": [
{ 
  "lat":50.994854, "lon":-114.071649, 
  "add":"6455 Macleod Trail SW, Calgary, AB, T2H 0K3, Canada", 
  "sadd":"6455 Macleod Trail SW, Calgary", 
  "pho":"(403) 259-2274", "wf":false
},{
  "lat":51.064404, "lon":-114.096480, 
  "add":"1632 14th Avenue NW, Calgary, AB, T2N 1M7, Canada", 
  "sadd":"1632 14th Avenue NW, Calgary", "pho":"(403) 210-1266", "wf":true
}, {
  "lat":51.046615, "lon":-114.067489, 
  "add":"225 7 Avenue SW, Calgary, AB, T2P 2W3, Canada", 
  "sadd":"225 7 Avenue SW, Calgary", "pho":"(403) 266-5457", "wf":true
},
  ...
  ...
  ...
]
}

Now, when I have the framework for building maps, it takes me minutes to create a new working Google Maps application. No manual work – the map, the filters and the table are all built on the fly as defined by the metadata. I am able to reuse the most of the framework's code without actually changing it. Thus, less skill is required from a JavaScript developer to build a new map using the framework. The developer doesn't even need to know how Google Maps actually work...

Comments (2)

  • Comment by Stephen Kenny — August 3, 2007 @ 1:22 pm

    We are releasing a map based CD product that allows outdoor enthusiasts to plan their hiking adventure in the Canadian Rockies. We are using Memory Map as the mapping engine. Our expertise is in the creation of the Topo, trail, elevation model data with WEB linkages that are relevant in the planning process. What are your thoughts on using the Google mapping API to drive the application off the WEB.

    Stephen

  • Comment by Pavel Simakov — August 3, 2007 @ 1:43 pm

    Stephen,

    Thank for reading Software Secret Weapons!

    For the shrink-wrap product shipped on the CD the embedded mapping engine is probably the best. But if you plan to deliver collaborative web-based applications – Google Maps API is likely the choice. I found it very easy to build web apps using Google Maps. Front end developers will require advanced CSS, DHTML, AJAX, XML parsing and JavaScript skills (with closures). Various forms of server-side support for AJAX will also be required. But overall – Google Maps works very very well for the web.

    On the other hand, I am not sure if Google Maps API is powerful enough when compared to the embedded mapping engine. For example: the elevations are not really supported. You have to perform detailed feature comparison from the pure mapping prospective before going ahead.

    Don’t forget about Google Earth! This might be another great platform for a trip planning software. I actually think there is one already called Trimble Outdoors Trips layer in Google Earth here http://www.trimbleoutdoors.com/GoogleEarthLayer.aspx

    Good luck,

    - Pavel Simakov


Leave a comment


  Copyright © 2004-2014 by Pavel Simakov
any conclusions, recommendations, ideas, thoughts or the source code presented on this site are my own and do not reflect a official opinion of my current or past employers, partners or clients