Hello world.
I'm posting this more for my own future reference than anything but if anyone else finds it useful then please let me know where you used it and what for.
I've been working on a few sites recently in Umbraco and I've built up a media system for it (that I'll probably post as well if we can find a way to attach code files) that you can post any media content into a page; the current list of media types includes but is not limited to images, downloads, flash, flash video (FLV), audio, quicktime, quicktime VR and Google maps. The mapping stuff provided the biggest Javscript challenge so I thought I'd post the code here for posterity. The code is based on Mootools but could easily be re-implemented with JQuery or Prototype - it's not exactly complex. The nice thing about this method it is that the GM code doesn't get loaded unless there are some maps divs in the page, so the usual delay from loading code off Google's servers doesn't happen until the page has loaded and it all feels a bit quicker even though technically I suspect it's slower.
Code for gmaps.js:
window.addEvent('domready', function() {
if($$(".gmap").length > 0){
$$(".gmap").each(function(gmap, i) {
if(i == 0){
var props = gmap.getProperty("data").split("~");
var gmkey = props[4];
var gscr = new Element("script", {
"type":"text/javascript",
"src":"http://www.google.com/jsapi?key="+gmkey+"&callback=LoadMaps"
});
gscr.injectAfter($E("head"));
}
});
}
});
function LoadMaps()
{
google.load("maps", "2", {"callback" : InitMaps});
}
function InitMaps()
{
$$(".gmap").each(function(gmap,i){
//grab all the map properties from the data property
var props = gmap.getProperty("data").split("~");
var address = props[0];
var postcode = props[1];
var zoom = parseInt(props[2]);
var driving = props[3];
var ll = props[5];
var title = gmap.getProperty("title");
var apoint;
var geocoder = new GClientGeocoder();
geocoder.getLatLng(address+","+postcode,function(point){
if(!point)
{
var lls = ll.split(",")
point = new GLatLng(lls[0], lls[1])
}
if(point){
SetMap(gmap, point, title, zoom, driving, address+","+postcode);
}else{
gmap.remove();
}
});
});
}
function SetMap(gmap, point, title, zoom, driving, address){
var map = new google.maps.Map2(gmap);
var mapTypes = map.getMapTypes();
map.setCenter(point, zoom, mapTypes[0]);
if(driving == "1" && (address.length > 3)){
var bubble = document.createElement("p");
bubble.setAttribute("align", "left");
bubble.setAttribute("style", "font-family:arial");
bubble.innerHTML = "<b>"+title+"</b><br />Get directions from:<br /><input type=\"text\" id=\"from_location\" /><input type=\"button\" value=\"Go\" onclick=\"window.open('http://maps.google.co.uk/maps?f=d&hl=en&saddr=' + document.getElementById('from_location').value + '&daddr="+escape(address)+"');\"/>";
map.openInfoWindow(map.getCenter(), bubble);
}
else{
map.addOverlay(new GMarker(point));
}
}
To implement this, you just need to include the above code in an external js file and put this on the page:
<div id="{7}-maps" class="gmap" title="{0}" data="{3}~{4}~{5}~{6}~{8}~{9}" style="width: {1}px; height: {2}px"></div>
Where:
{0} = title (used in the div title and the driving directions bubble)
{1} = width of the maps container
{2} = height of the maps container
{3} = 1st line of address
{4} = postcode
{5} = zoom level
{6} = driving directions ("0" = no, "1" = yes)
{7} = random string in case of there is more than one map on the page
{8} = google API key
{9} = lat/long of address if 1st line/postcode doesn't give the proper location
If {3} and {4} don't manage to find an address through the Geolocation API then the code will fall back on {9}, and if that doesn't provide a map position then the code removes the container div from the DOM and exits.
I've tested it on IE7, Firefox/Win, Firefox/Linux, Opera. I'm aiming to test it on Safari and IE6 in the next couple of days. I'll post any fixes in the comments. Unless we can find a way to attach code files to blog posts. If anyone else finds issues let me know and I'll try to fix them. Suspects for bugs at the moment are the fact that I'm using a non-XHTML attribute to convey the data to Javascript and the use of innerHTML in the driving directions code.