KML overlays with GMap-enabled nodes
The GMap module is a highly useful tool for enabling Google Maps on Drupal nodes, and its integration with Location has made it the de-facto choice for this functionality on most Drupal sites. On a recent project, I was looking for a quick way to allow a user to attach KML files to a Gmap-enabled node through a CCK field and have them integrated into the resulting map. An initial search suggested GMap Addons as a potential solution given its inclusion of overlay support, but its lack of documentation and reliance on macros make it a rather counter-intuitive process to deal with, especially given the ease of use of Google Maps’ original API. So we’re back to figuring it out with the initial Gmap module itself.
A little digging into its code yielded this key method: Drupal.gmap.getMap(mapid)
This allows you to retrieve the JS map object that will be generated, which is exactly what we need in this case. The GGeoXml class from the Google Maps API then provides us with the other half, the ability to parse the KML file to then attach it to this object.
What follows is a quick hook that associates KML files uploaded to the node’s field_file_kml field to the map. Since this is obviously dependent on GMap being enabled and configured, we’re assuming the value for googlemap_api_key has been set here.
<?php
function kml_support_nodeapi(&$node, $op, $a3 = <span class="caps">NULL</span>, $a4 = <span class="caps">NULL</span>) {
// Only applies to this content type
if ($node->type != 'your_content_type') {
return;
}
if ($op != 'view') {
return;
}
if (empty($node->field_file_kml)) {
return;
}
$data .= '</script><script src="http://maps.google.com/maps?file=api&v=2&key=' . variable_get('googlemap_api_key', '') . '" type="text/javascript"></script>';
$data .= '<script type="text/javascript">
$(document).ready(function() {
var map = Drupal.gmap.getMap("google_map").map;
map.addControl(new GLargeMapControl());';
foreach ($node->field_file_kml as $id => $kml_file) {
$url = file_create_url($kml_file['filepath']);
$data .= 'var geoXml' . $id . ';';
$data .= 'geoXml' . $id . ' = new GGeoXml("' . $url . '");';
$data .= 'map.addOverlay(geoXml' . $id . ');';
}
$data .= '});';
drupal_add_js($data, 'inline');
}
?>



Comments
a few thoughts
Just a few comments on code style.
I'd recommend using url() to create your URLs.
Also I'd suggest using drupal_add_js() twice. Once to add the external js file (with 'module' instead of 'inline'). This will eliminate the need for the crufty leading </script>
Then you can add the jQuery stuff like you did, but without surrounding script tags.
Re: a few thoughts
Hi Dave,
Thanks for the comment. If I'm not mistaken, drupal_add_js() doesn't currently support external files, but that is planned for 7.
As for the creation of the URL, url() will not work for a file, even with the absolute parameter set to true. But there is file_create_url() for this purpose, so I'll definitely be using that instead.
Where does this code go, and need to create a cck file field?
So this code goes in template.php, and a cck file field must be created?
Attempted those couple things using drupal 6, and uploaded a KML file using the new cck file upload field with no success.
This is a hack to gmap.module --- isn't it?
As I read this, it's a hack to gmap.module itself. So that when a text field containing some KML code in the CCK definition of a Google Earth viewer page is present, that KML is passed to the GE API for display.
At least I think that is what it is.
I'd like to see this working myself.
A couple of thoughts: There should be some checking so that a KML file for Google Earth is not passed to a terrain or street map, although GE might know enough to deal with that.
A safety net would be to run the KML text file through some kind of sanity checker and print an error if non-valid KML is discovered. That would make development at a content level easier.
Anyone gets this working send me and email, I have a GPS track of a snowmachine trek in Alaska I'd like to display on a web page.
hook_nodeapi
Sorry for the late response everyone. This is not a hack in the module itself, but an implementation of hook_nodeapi, so it should be placed in a new custom module (ex: kml_support.module) in sites/default/modules/.
You'll also need to create the corresponding kml_support.info file and enable the module. Keep in mind you may have to change the code depending on what name you've used for the CCK file field that stores the KML file (in this case it's field_file_kml).
I wrote this for Drupal 5.x, but the API confirms that hook_nodeapi hasn't changed in 6.x.
Hi Tirdad, Hey thanks for the
Hi Tirdad, Hey thanks for the great tip, I've been frustrated with the gmap_addons too. Tried your advice on Drupal6.10 without success. Drupal.gmap.getMap("gmap-id").map doesn't seem to be returning anything. Tried initialising the map as suggested here (http://drupal.org/node/150939) but no luck. Any idea what I could be missing?
I’d say make sure you have
I’d say make sure you have the right map id. I found it by looking at the source of the Google Map’s div:
<div id="gmap-google_map-gmap0" ....>In this case the id was google_map, the gmap- prefix and -gmap0 suffix being added automatically by the Gmap module.
Hi Tirdad, Thanks for the
Hi Tirdad,
Thanks for the feedback... I had the map ID correct. Not sure why this is not working. Found that the trackfield module will actually allow attaching of kml to nodes and displaying as maps. yay!
Possible reason its not working for you
Possibly you have run into the same issue discussed (and solved) here http://drupal.org/node/150939#comment-1285426. Basically the object isn't ready when you try to reference it.
Post new comment