diff --git a/mod/data/field/latlong/field.class.php b/mod/data/field/latlong/field.class.php
new file mode 100755
index 0000000000000..0d18e14cbf56f
--- /dev/null
+++ b/mod/data/field/latlong/field.class.php
@@ -0,0 +1,174 @@
+ "http://maps.google.com/maps?q=@lat@,+@long@&iwloc=A&hl=en",
+ "Google Earth" => "@wwwroot@/mod/data/field/latlong/kml.php?d=@dataid@&fieldid=@fieldid@&rid=@recordid@",
+ "Geabios" => "http://www.geabios.com/html/services/maps/PublicMap.htm?lat=@lat@&lon=@long@&fov=0.3&title=Moodle%20data%20item",
+ "OpenStreetMap" => "http://www.openstreetmap.org/index.html?lat=@lat@&lon=@long@&zoom=11",
+ "Multimap" => "http://www.multimap.com/map/browse.cgi?scale=200000&lon=@long@&lat=@lat@&icon=x"
+ );
+ // Other map sources listed at http://kvaleberg.com/extensions/mapsources/index.php?params=51_30.4167_N_0_7.65_W_region:earth
+
+
+
+ function data_field_latlong($field=0, $data=0) {
+ parent::data_field_base($field, $data);
+ }
+
+ function display_add_field($recordid=0){
+ global $CFG;
+
+ $lat = '';
+ $long = '';
+
+ if ($recordid){
+ if ($content = get_record('data_content', 'fieldid', $this->field->id, 'recordid', $recordid)) {
+ $lat = $content->content;
+ $long = $content->content1;
+ }
+ }
+
+ $str = '
';
+ $str .= '
';
+ $str .= '
';
+
+ return $str;
+ }
+
+ function display_browse_field($recordid, $template) {
+ global $CFG;
+ if ($content = get_record('data_content', 'fieldid', $this->field->id, 'recordid', $recordid)){
+ $lat = empty($content->content)? '':$content->content;
+ $long = empty($content->content1)? '':$content->content1;
+
+ if (empty($lat) or empty($long)) {
+ return '';
+ }
+
+ if($lat < 0) {
+ $compasslat = "" . sprintf('%01.4f', 0 - $lat) . '°S';
+ } else {
+ $compasslat = "" . sprintf('%01.4f', $lat) . "°N";
+ }
+ if($long < 0) {
+ $compasslong = "" . sprintf('%01.4f', 0 - $long) . '°W';
+ } else {
+ $compasslong = "" . sprintf('%01.4f', $long) . "°E";
+ }
+
+ $str = '';
+
+ return $str;
+ }
+ return false;
+ }
+
+ function update_content($recordid, $value, $name='') {
+ $content = new object;
+ $content->fieldid = $this->field->id;
+ $content->recordid = $recordid;
+
+ $names = explode('_', $name);
+ switch ($names[2]){
+ case 0: // update lat
+ $content->content = (float)$value;
+ break;
+ case 1: // update long
+ $content->content1 = (float)$value;
+ break;
+ default:
+ break;
+ }
+
+ if ($oldcontent = get_record('data_content','fieldid', $this->field->id, 'recordid', $recordid)) {
+ $content->id = $oldcontent->id;
+ return update_record('data_content', $content);
+ } else {
+ return insert_record('data_content', $content);
+ }
+ }
+
+ function get_sort_sql($fieldname) {
+ global $CFG;
+
+ switch ($CFG->dbtype) {
+ case 'mysql': // string in an arithmetic operation is converted to a floating-point number
+ return '('.$fieldname.'+0.0)';
+
+ default:
+ return 'CAST('.$fieldname.' AS REAL)';
+ }
+ }
+}
+
+?>
\ No newline at end of file
diff --git a/mod/data/field/latlong/icon.gif b/mod/data/field/latlong/icon.gif
new file mode 100644
index 0000000000000..ec54dc1507c76
Binary files /dev/null and b/mod/data/field/latlong/icon.gif differ
diff --git a/mod/data/field/latlong/kml.php b/mod/data/field/latlong/kml.php
new file mode 100644
index 0000000000000..d1170958ea3ef
--- /dev/null
+++ b/mod/data/field/latlong/kml.php
@@ -0,0 +1,141 @@
+dataid)) {
+ error('Data ID is incorrect');
+ }
+ if (! $course = get_record('course', 'id', $data->course)) {
+ error('Course is misconfigured');
+ }
+ if (! $cm = get_coursemodule_from_instance('data', $data->id, $course->id)) {
+ error('Course Module ID was incorrect');
+ }
+ if (! $field = get_record('data_fields', 'id', $fieldid)) {
+ error('Field ID is incorrect');
+ }
+ if (! $field->type == 'latlong') { // Make sure we're looking at a latlong data type!
+ error('Field ID is incorrect');
+ }
+ if (! $content = get_record('data_content', 'fieldid', $fieldid, 'recordid', $rid)) {
+ error('Field content not found');
+ }
+} else { // We must have $d
+ if (! $data = get_record('data', 'id', $d)) {
+ error('Data ID is incorrect');
+ }
+ if (! $course = get_record('course', 'id', $data->course)) {
+ error('Course is misconfigured');
+ }
+ if (! $cm = get_coursemodule_from_instance('data', $data->id, $course->id)) {
+ error('Course Module ID was incorrect');
+ }
+ if (! $field = get_record('data_fields', 'id', $fieldid)) {
+ error('Field ID is incorrect');
+ }
+ if (! $field->type == 'latlong') { // Make sure we're looking at a latlong data type!
+ error('Field ID is incorrect');
+ }
+ $record = NULL;
+}
+
+require_course_login($course, true, $cm);
+
+/// If it's hidden then it's don't show anything. :)
+if (empty($cm->visible) and !isteacher($course->id)) {
+ $strdatabases = get_string("modulenameplural", "data");
+ $navigation = "id\">$strdatabases ->";
+ print_header_simple(format_string($data->name), "",
+ "$navigation ".format_string($data->name), "", "", true, '', navmenu($course, $cm));
+ notice(get_string("activityiscurrentlyhidden"));
+}
+
+/// If we have an empty Database then redirect because this page is useless without data
+if (isteacher($course->id)) {
+ if (!record_exists('data_fields','dataid',$data->id)) { // Brand new database!
+ redirect($CFG->wwwroot.'/mod/data/field.php?d='.$data->id); // Redirect to field entry
+ }
+}
+
+
+
+
+//header('Content-type: text/plain'); // This is handy for debug purposes to look at the KML in the browser
+header('Content-type: application/vnd.google-earth.kml+xml kml');
+header('Content-Disposition: attachment; filename="moodleearth-'.$d.'-'.$rid.'-'.$fieldid.'.kml"');
+
+//print_r($record);
+
+echo data_latlong_kml_top();
+
+if($rid) { // List one single item
+ $pm->name = "Item #$rid";
+ $pm->description = "<a href='$CFG->wwwroot/mod/data/view.php?d=$d&rid=$rid'>Item #$rid</a> in Moodle data activity";
+ $pm->long = $content->content1;
+ $pm->lat = $content->content;
+ echo data_latlong_kml_placemark($pm);
+} else { // List all items in turn
+
+ $contents = get_records('data_content', 'fieldid', $fieldid);
+
+ foreach($contents as $content) {
+ $pm->name = "Item #$content->recordid";
+ $pm->description = "<a href='$CFG->wwwroot/mod/data/view.php?d=$d&rid=$content->recordid'>Item #$content->recordid</a> in Moodle data activity";
+ $pm->long = $content->content1;
+ $pm->lat = $content->content;
+ echo data_latlong_kml_placemark($pm);
+ }
+
+}
+
+echo data_latlong_kml_bottom();
+
+
+
+
+function data_latlong_kml_top() {
+ return '
+
+
+';
+}
+
+function data_latlong_kml_placemark($pm) {
+ return '
+ '.$pm->description.'
+ '.$pm->name.'
+
+ '.$pm->long.'
+ '.$pm->lat.'
+ 30500.8880792294568
+ 46.72425699662645
+ 0.0
+
+ 0
+
+ 1
+ relativeToGround
+ '.$pm->long.','.$pm->lat.',50
+
+
+';
+}
+
+function data_latlong_kml_bottom() {
+ return '';
+}
+
diff --git a/mod/data/field/latlong/mod.html b/mod/data/field/latlong/mod.html
new file mode 100755
index 0000000000000..03adc77391504
--- /dev/null
+++ b/mod/data/field/latlong/mod.html
@@ -0,0 +1,24 @@
+