Google Maps API in 6.x using Blocks and CCK Field

Last modified: August 14, 2008 - 19:46

I was looking for a way to use the Google API for mapping in a block but that would work for every node in a particular content type. This code is based on the fact that a value is contained in a CCK field called field_address. If it's blank, the map will not display. If it's there, it will (there is no error checking on if it's valid other than a javascript popup). I am also not cleaning the address field because posts on my site are all moderated. I wrote this quick fix to tide me over until a good mapping module is ported to 6.x.

The address field can be either street,city,state or in the google maps lat/long format.

An example can be seen here: Day Trips Canada -- Simply click on any node from the front page to see how it works. Map/Real-time directions are at the bottom.

<?php
if(arg(0)=='node' && is_numeric(arg(1)) && (arg(2)!='edit') && (arg(2)!='delete')) {
  if (
$node = node_load(arg(1))) {
    if (
$node->type == "trip") {
      if (
$node->field_address) {
        if (
$node->field_address[0]['value']) {
?>

<script src=" http://maps.google.com/?file=api&amp;v=2.x&amp;key=<put your key here>" type="text/javascript"></script>
<style type="text/css">
table.directions th {
background-color:#EEEEEE;
}
</style>
<script type="text/javascript">
    var map;
    var gdir;
    var geocoder = null;
    var addressMarker;

    function initialize() {
      if (GBrowserIsCompatible()) {     
        map = new GMap2(document.getElementById("map_canvas"));
        map.addControl(new GSmallMapControl());
        map.addControl(new GMapTypeControl());
        gdir = new GDirections(map, document.getElementById("directions"));
        GEvent.addListener(gdir, "load", onGDirectionsLoad);
        GEvent.addListener(gdir, "error", handleErrors);

        setDirections("Toronto, Ontario", "<?php print_r($node->field_address[0]['value']); ?>", "en_US");
      }
    }
   
    function setDirections(fromAddress, toAddress, locale) {
      gdir.load("from: " + fromAddress + " to: " + toAddress,
                { "locale": locale });
    }

    function handleErrors(){
   if (gdir.getStatus().code == G_GEO_UNKNOWN_ADDRESS)
     alert("No corresponding geographic location could be found for one of the specified addresses. This may be due to the fact that the address is relatively new, or it may be incorrect.\nError code: " + gdir.getStatus().code);
   else if (gdir.getStatus().code == G_GEO_SERVER_ERROR)
     alert("A geocoding or directions request could not be successfully processed, yet the exact reason for the failure is not known.\n Error code: " + gdir.getStatus().code);
  
   else if (gdir.getStatus().code == G_GEO_MISSING_QUERY)
     alert("The HTTP q parameter was either missing or had no value. For geocoder requests, this means that an empty address was specified as input. For directions requests, this means that no query was specified in the input.\n Error code: " + gdir.getStatus().code);
 
   else if (gdir.getStatus().code == G_GEO_BAD_KEY)
     alert("The given key is either invalid or does not match the domain for which it was given. \n Error code: " + gdir.getStatus().code);

   else if (gdir.getStatus().code == G_GEO_BAD_REQUEST)
     alert("A directions request could not be successfully parsed.\n Error code: " + gdir.getStatus().code);
   
   else alert("An unknown error occurred.");
  
}

function onGDirectionsLoad(){
      // Use this function to access information about the latest load()
      // results.

      // e.g.
      // document.getElementById("getStatus").innerHTML = gdir.getStatus().code;
  // and yada yada yada...
}
</script>
<body onload="initialize()" onunload="GUnload()">
<form action="#" onsubmit="setDirections(this.from.value, this.to.value, this.locale.value); return false">
<input type="hidden" id="locale" name="locale" value="en">
<b>From:</b> <input type="text" size="25" id="fromAddress" name="from" value="Toronto, Ontario"/>&nbsp;&nbsp;<b>To:</b>&nbsp;<input type="text" size="25" id="toAddress" readonly name="to" value="<?php print_r($node->field_address[0]['value']); ?>" />
&nbsp;&nbsp;<input name="submit" type="submit" value="Get Directions" />
</form>

<br/>
<table class="directions">
<tr><th>Formatted Directions</th><th>Map</th></tr>
<tr>
<td valign="top"><div id="directions" style="width: 280px"></div></td>
<td valign="top"><div id="map_canvas" style="width: 330px; height: 400px"></div></td>
</tr>
</table><br>
<small><b>How to use:</b> Type in your starting address by either City/Province or Street, City, Province and click the "Get Directions" button.</small>
<?php
     
}
    }
  }
}
}
?>

Combined with Content Template for GeoRSS Points

sampeckham - July 18, 2008 - 13:44

Thanks for this tip.

To further elaborate, I combined some of this with playing around with Content Template module, to affect the RSS of one of my Content Types and created a GeoRSS to feed into the map. The difference this makes to the above, is having all your locations shown on one map.

Add Long/Lat fields to your content type (with CCK), then using the contemplate module, go to the RSS feed for that content type and add something similar to this.

<?php
  $latitude
= $node->field_latitude[0]['value'];
 
$longitude = $node->field_longitude[0]['value'];
 
$geocode = $latitude.' '.$longitude;
 
$xml_elements = array(
    array(
     
'key' => 'georss:point',
     
'value' => $geocode,
         ),
   );
?>

This will add the simple GeoRSS tags to your RSS.

Next create a View for the content type and create a 'feed' view. Set the path for that feed and add it to the 'initialize' function above. Or something like this will work.

function initialize() {
  if (GBrowserIsCompatible()) {
        geoXml = new GGeoXml("YOUR FEED HERE");
map = new GMap2(document.getElementById("map_canvas"));
    map.setCenter(new GLatLng(34.30714385628804, -2.109375), 1);
map.addControl(new GLargeMapControl());
    map.addControl(new GLargeMapControl());
    map.addOverlay(geoXml);
  }
}

I stuck my Google map in a block, to show all the points above a list of nodes.

 
 

Drupal is a registered trademark of Dries Buytaert.