Tuesday, July 14, 2009

Grails, jQuery, and Yahoo Maps

I recently completed a new NetCenter365 feature that uses Yahoo Maps to show the location of all current customers. Here's a screenshot:


I really appreciate Yahoo's "Maps Web Services" which include a helpful geolocation service.

First, we map out HQ with:
 var map = new YMap(document.getElementById('map'));
map.addTypeControl(); map.addZoomLong(); map.addPanControl();
map.setMapType(YAHOO_MAP_REG);

var hq = new YGeoPoint(HQ.latitude, HQ.longitude);
map.drawZoomAndCenter(hq, 11);
Then we use grails and jquery to loop through every customer and fire off the following ajax requests:
 var url = '${createLink(controller: "location", action: "latlong")}' + "/";

<g:each var="account" in="${accounts}">
$.getJSON(url + ${account.id}, function(x) {
var pt = new YGeoPoint(x.latitude, x.longitude);
var m = new YMarker(pt);
m.addAutoExpand('${account.name.encodeAsJavaScript()}');
map.addOverlay(m);
});
</g:each>
The heart of the location/latlong method uses Yahoo's geolocation services. Here's a snippet of the groovy code:
 def geocoder = "http://local.yahooapis.com/MapsService/V1/geocode?appid=${APPID}"
if (account.line1) geocoder += "&street=" + URLEncoder.encode(account.line1);
if (account.city) geocoder += "&city=" + URLEncoder.encode(account.city);
if (account.state) geocoder += "&state=" + account.state;
if (account.zip) geocoder += "&zip=" + account.zip;

def xml = geocoder.toURL().text
def records = new XmlParser().parseText(xml);
location.latitude = records.Result[0].Latitude.text()
location.longitude = records.Result[0].Longitude.text()
Performance wise, the map pops up quite quickly and the markers appear in rapid procession. This is aided by caching Lat/Long info to minimize geolocation requests.

No comments: