MikeH
MikeH

Reputation: 866

Using JSON Data to Populate a Google Map with Database Objects

I'm revising this question after reading the resources mentioned in the original answers and working through implementing it.

I'm using the google maps api to integrate a map into my Rails site. I have a markets model with the following columns: ID, name, address, lat, lng.

On my markets/index view, I want to populate a map with all the markets in my markets table. I'm trying to output @markets as json data, and that's where I'm running into problems. I have the basic map displaying, but right now it's just a blank map. I'm following the tutorials very closely, but I can't get the markers to generate dynamically from the json. Any help is much appreciated!

Here's my setup:

Markets Controller:

def index
   @markets = Market.filter_city(params[:filter])
     respond_to do |format|
     format.html # index.html.erb
     format.json { render :json => @market}
     format.xml  { render :xml => @market }
  end
end

Markets/index view:

<head>
    <script type="text/javascript"
      src="http://www.google.com/jsapi?key=GOOGLE KEY REDACTED, BUT IT'S THERE" >
</script>
<script type="text/javascript">
    var markets = <%= @markets.to_json %>;
</script>
<script type="text/javascript" charset="utf-8">
    google.load("maps", "2.x");
    google.load("jquery", "1.3.2");
  </script>
</head>
<body>    
    <div id="map" style="width:400px; height:300px;"></div> 
</body>    

Public/javascripts/application.js:

function initialize() {   
  if (GBrowserIsCompatible() && typeof markets != 'undefined') {
    var map = new GMap2(document.getElementById("map"));
    map.setCenter(new GLatLng(40.7371, -73.9903), 13);
    map.addControl(new GLargeMapControl());

function createMarker(latlng, market) {
  var marker = new GMarker(latlng);
  var html="<strong>"+market.name+"</strong><br />"+market.address;
  GEvent.addListener(marker,"click", function() {
    map.openInfoWindowHtml(latlng, html);
  });
  return marker;
}

var bounds = new GLatLngBounds;
for (var i = 0; i < markets.length; i++) {
  var latlng=new GLatLng(markets[i].lat,markets[i].lng)
  bounds.extend(latlng);
  map.addOverlay(createMarker(latlng, markets[i]));
}

} }

window.onload=initialize;  
window.onunload=GUnload;    

Upvotes: 4

Views: 5354

Answers (2)

Andy Gaskell
Andy Gaskell

Reputation: 31761

The approach I took in creating a prototype was to not have the html version of the view be responsible for creating the map and placing the markers. What I did was use the Google Maps API, jQuery, ajax and json. My page initially loads, then makes a request for the json (which would be a list of your markets). Once I have the json I create the map and add the markers with jQuery and the Google Maps API.

Here's a good tutorial for getting started with jQuery and Google Maps.

Edit: here's how I'd simplify it to get started - once this is working then add the html and event stuff back in.

function createMarker(latlng, market) {
  return new GMarker(latlng);
}

$(function() {
  if (GBrowserIsCompatible() && typeof markets != 'undefined') {
    var map = new GMap2(document.getElementById("map"));
    map.setCenter(new GLatLng(40.7371, -73.9903), 13);
    map.addControl(new GLargeMapControl());

    $(markers).each(function(i, obj) {
      var m = obj.market; // this *might* be var m = obj;
      var latlng = new GLatLng(m.lat, m.lng); // check m.lat and m.lng in FireBug
      map.addOverlay(createMarker(latlng, m));
    });
  }
});

Upvotes: 0

Bob Nadler
Bob Nadler

Reputation: 1277

Not sure if you're only looking for free resources, but the book Advanced Rails Recipes has a pretty good write up on this. You can get the source code from the Pragmatic Programmer's site (I'd recommend getting the book, too).

Upvotes: 0

Related Questions