When Grand Rapids WiFi–then a PHP application–first implemented google map support all the logic for producing those maps came in the templates. The controller passed the view a list of locations for that page, and it wrote out a series of javascript calls that produced the map. It was a little unreliable and very clunky, but it worked. When I moved the app over to rails, that was one aspect that I didn’t change, and it continued to work.

With more and more talk lately of google and lock-in, and some desire to begin to do more with the maps (perhaps invoking the ajax buzzword) I realised that I needed better tools and cleaner abstraction to work with the map. And it just so happened that YM4R_Mapstraction appeared at just the right time.

YM4R_Mapstraction is a rails plugin that provides methods to build map objects in your controller and helpers that will turn that into a map in the view. Controller code looks like:

@map = Mapstraction.new('map', :google)
@map.control_init(:small => true)
@map.center_zoom_init([location.latitude, location.longitude], 11)
@map.marker_init(Marker.new([location.latitude, location.longitude],
    :label => location.name, :info_bubble => location.description))

and view code would be:

in the header, and

 300, :height => 300) %>

where you want your map to appear in the page.

To switch from a google map to a yahoo map, you simply need to replace ‘:google’ with ‘:yahoo’ in the examples above, opening up the possibility of automatically checking for server availability, or of allowing users to choose their preferred map.

One thing I found frustrating was simply having text for the description in the info bubble. That was easily solved by creating a partial called _bubble.rhtml and changing the marker code to:

@map.marker_init(Marker.new([location.latitude, location.longitude],
    :label => location.name,
    :info_bubble => render_to_string(:partial => 'bubble')))

So far, using the partials doesn’t seem to slow things down too much, but eventually I hope to cache the partials to reduce any overhead that might introduce.

What I’ve not yet discovered (and may not be implemented) is a way to automatically center and zoom a map. It would be very nice to be able to add a batch of points to a map and have the plugin automatically work out their mid-point. Maybe I need to work on that a little…