Index: /main/trunk/greenstone2/perllib/doc.pm
===================================================================
--- /main/trunk/greenstone2/perllib/doc.pm	(revision 33124)
+++ /main/trunk/greenstone2/perllib/doc.pm	(revision 33125)
@@ -42,4 +42,9 @@
 ##use hashdoc;
 use docprint;
+use JSON;
+
+# We just need pi from the Trig lib
+# Import constants pi2, pip2, pip4 (2*pi, pi/2, pi/4).
+use Math::Trig ':pi';
 
 # the document type may be indexed_doc, nonindexed_doc, or
@@ -1129,9 +1134,189 @@
 			
 			#Only add the metadata if it has not already been added
-			my $metaMap = $self->get_metadata_hashmap($section);
+			my $metaMap = $self->get_metadata_hashmap($section); ### TODO: metaMap not used. Unnecesssary step? (Called function has no side-effects.)
 		}
 	}
 
+	elsif($field eq "GPS.mapOverlay") { # then the value is a JSON string
+		print STDERR "GPS.mapOverlay before val: " . $value . "\n";
+		
+		# TODO html decode?
+		$value =~ s@&#091;@[@g;
+		$value =~ s@&#093;@]@g;
+		$value =~ s@&quot;@"@g;
+		print STDERR "GPS.mapOverlay after val: " . $value . "\n";
+
+		my $json_array = decode_json $value;
+		#my $json = JSON->new->allow_nonref;
+		#&printAllShapes($json, $json_array);
+
+		foreach my $shape (@$json_array) {		
+
+			my $type = $shape->{"type"};
+			print STDERR "Type : " . $type . "\n";
+		
+			if($type eq "circle") {
+				#print STDERR "Found a circle:\n" . &printShape($json, $shape);
+		
+				# work out bounding box
+				# SCARY!
+				# want the inverse of this useful page:
+				# https://stackoverflow.com/questions/639695/how-to-convert-latitude-or-longitude-to-meters
+				# https://www.geodatasource.com/developers/javascript		
+				
+							
+				# for now, just process the circle centre
+				#my $centre = $shape->{"center"};				
+				#$self->processLatOrLng($section_ptr, "Latitude", $centre->{"lat"});
+				#$self->processLatOrLng($section_ptr, "Longitude", $centre->{"lng"});
+
+				
+				# Dr Bainbridge wants us to use: https://gis.stackexchange.com/questions/5821/calculating-latitude-longitude-x-miles-from-point
+				# But we're using the rule of thumb here, since for N,E,S,W it works out the same:
+				# https://gis.stackexchange.com/questions/2951/algorithm-for-offsetting-a-latitude-longitude-by-some-amount-of-meters
+				# which states
+				# "If your displacements aren't too great (less than a few kilometers) and you're not right at the poles,
+				# use the quick and dirty estimate that 111,111 meters (111.111 km) in the y direction is 1 degree
+				# (of latitude) and 111,111 * cos(latitude) meters in the x direction is 1 degree (of longitude)."
+				my $centre_lat = $shape->{"center"}->{"lat"};
+				my $centre_lng = $shape->{"center"}->{"lng"};
+				my $radius = $shape->{"radius"}; # in metres!
+
+				print STDERR "@@@ circle centre: ($centre_lat, $centre_lng), radius: $radius\n";
+
+				my $lat_north = $centre_lat + ($radius/111111);
+				my $lat_south = $centre_lat - ($radius/111111);
+				
+				print STDERR "### lat_north:  $lat_north\n"; 
+				print STDERR "### lat_south:  $lat_south\n";
+
+				# our latitude and longitude values are in degrees. But cos and sin etc in perl and generally all prog languages
+				# all expect their angle to be in radians. So need to convert from degree to radians before we can take the cose of it.
+				my $centre_lat_radians = $self->degreesToRadians($centre_lat);
+				my $cos_in_radians = cos($centre_lat_radians);				
+				print STDERR "cos $centre_lat_radians " . cos($centre_lat_radians) . "\n";
+				my $lng_east = $centre_lng + ($radius/(111111 * $cos_in_radians));
+				my $lng_west = $centre_lng - ($radius/(111111 * $cos_in_radians));
+				print STDERR "### lng_east  $lng_east\n"; 
+				print STDERR "### lng_west  $lng_west\n";
+
+
+
+				my $cos_lat = cos($centre_lat);				
+				print STDERR "cos $centre_lat is $cos_lat\n";
+
+				$self->processCoordinate($section_ptr, $lat_north, $lng_east);				
+				$self->processCoordinate($section_ptr, $lat_south, $lng_east);
+				$self->processCoordinate($section_ptr, $lat_south, $lng_west);
+				$self->processCoordinate($section_ptr, $lat_north, $lng_west);
+			
+			}
+			elsif ($type eq "marker") {
+				print STDERR "@@ MARKER FOUND WITH LAT: " . $shape->{"position"}->{"lat"} . "\n";
+				print STDERR "@@ MARKER FOUND WITH LNG: " . $shape->{"position"}->{"lng"} . "\n";
+				$self->processCoordinate($section_ptr, $shape->{"position"}->{"lat"}, $shape->{"position"}->{"lng"});				
+			}
+			elsif ($type eq "polyline" || $type eq "polygon") {
+				my $path_array = $shape->{"path"};
+				foreach my $position (@$path_array) {									
+					$self->processCoordinate($section_ptr, $position->{"lat"}, $position->{"lng"});
+				}
+			}
+			elsif ($type eq "rectangle") {
+		
+				my $bounds = $shape->{"bounds"};				
+			
+				$self->processCoordinate($section_ptr, $bounds->{"north"}, $bounds->{"east"});
+				$self->processCoordinate($section_ptr, $bounds->{"south"}, $bounds->{"east"});
+				$self->processCoordinate($section_ptr, $bounds->{"south"}, $bounds->{"west"});
+				$self->processCoordinate($section_ptr, $bounds->{"north"}, $bounds->{"west"});
+			}	
+		
+		} # end for on each shape in GPS.mapOverlay
+
+	} # end GPS.mapOverlay meta
+
     push (@{$section_ptr->{'metadata'}}, [$field, $value]);
+}
+
+# https://en.wikipedia.org/wiki/Radian
+sub degreesToRadians
+{
+	my $self = shift (@_);
+	my ($degrees) = @_;
+
+	return $degrees * pi /180; # returns radians
+}
+
+sub radiansToDegrees
+{
+	my $self = shift (@_);
+	my ($radians) = @_;
+
+	return $radians * 180 / pi; # returns degrees
+}
+
+sub printAllShapes {
+	my ($json, $json_array) = @_; 
+	
+	
+	#my $pretty_print_shape = $json->pretty->encode( $json_array->[0] ); 
+	foreach my $shape (@$json_array) {
+		my $pretty_print_shape = $json->pretty->encode( $shape ); 
+		print STDERR "Shape: $pretty_print_shape\n";
+		#&printShape($shape);
+	}
+	
+}	
+
+sub processCoordinate {
+	my $self = shift (@_);
+    my ($section_ptr, $latitude, $longitude) = @_;
+
+	my $lat_direction = ($latitude =~ m/^-/) ? "S" : "N";
+	my $lng_direction = ($longitude =~ m/^-/) ? "W" : "E";
+	
+	# have to store (lat, lng) in pairs, when there are so many coords to store
+	#push (@{$section_ptr->{'metadata'}}, ["Latitude", $latitude]);
+	#push (@{$section_ptr->{'metadata'}}, ["Longitude", $longitude]);
+
+	push (@{$section_ptr->{'metadata'}}, ["Coordinate", "$latitude $longitude"]); # "$latitude$lat_direction $longitude$lng_direction"
+
+	my ($latBeforeDec, $latAfterDec);
+	my ($lngBeforeDec, $lngAfterDec);
+
+	if($latitude !~ m/\./) {
+		$latBeforeDec = $latitude;
+		$latAfterDec = "";
+	} else {
+		($latBeforeDec, $latAfterDec) = ($latitude =~ m/^-?([0-9]+)\.([0-9]+)$/);
+	}
+	if($longitude !~ m/\./) {
+		$lngBeforeDec = $longitude;
+		$lngAfterDec = "";
+	} else {
+		($lngBeforeDec, $lngAfterDec) = ($longitude =~ m/^-?([0-9]+)\.([0-9]+)$/);
+	}	
+	
+	#if(defined $beforeDec && defined $afterDec)
+	#{
+		my $name = "CoordShort";
+		push (@{$section_ptr->{'metadata'}}, [$name, "$latBeforeDec$lat_direction $lngBeforeDec$lng_direction"]);
+			
+		for(my $i = 2; $i <= 4; $i++)
+		{
+			my $latDecPlaces = (length($latAfterDec) >= $i) ? substr($latAfterDec, 0, $i) : "";			
+			my $lngDecPlaces = (length($lngAfterDec) >= $i) ? substr($lngAfterDec, 0, $i) : "";
+
+			push (@{$section_ptr->{'metadata'}}, [$name, 
+					$latBeforeDec . $lat_direction. $latDecPlaces . " " . $lngBeforeDec . $lng_direction. $lngDecPlaces]);
+			
+		}
+			
+		#Only add the metadata if it has not already been added
+		#my $metaMap = $self->get_metadata_hashmap($section); ### TODO: metaMap not used. Unnecesssary step? (Called function has no side-effects.)
+	#}
+
+
 }
 
Index: /main/trunk/greenstone3/web/interfaces/default/js/map-scripts.js
===================================================================
--- /main/trunk/greenstone3/web/interfaces/default/js/map-scripts.js	(revision 33124)
+++ /main/trunk/greenstone3/web/interfaces/default/js/map-scripts.js	(revision 33125)
@@ -24,4 +24,6 @@
 	if(jsonNodeDiv.length)
 	{
+		console.log("@@@ JSON node div html: " + jsonNodeDiv.html());
+		
 		var jsonNodes = eval(jsonNodeDiv.html());
 		if(jsonNodes && jsonNodes.length > 0)
@@ -31,4 +33,5 @@
 				_docList[jsonNodes[i].nodeID] = jsonNodes[i];
 				_docList.ids.push(jsonNodes[i].nodeID);
+				console.log("@@@ JSON node: " + jsonNodes[i]);
 				createMarker(jsonNodes[i], true);
 			}
@@ -39,4 +42,5 @@
 			//$("#map_canvas").css({visibility:"hidden", height:"0px"});
 			$("#map_canvas").css({visibility:"hidden"});
+			//console.log("suppressing hiding the map");
 		}
 	}
@@ -82,5 +86,5 @@
 function setUpMap()
 {
-
+	//alert("@@@@in map-scripts::setUpMap()");
 	
 	var myOptions = 
@@ -93,4 +97,5 @@
 	
 	if ($map_canvas.length > 0) {
+		console.log("### map-scripts::setUpMap: map_canvas.exists");
 		_map = new google.maps.Map($map_canvas[0], myOptions);
 		google.maps.event.addListener(_map, 'bounds_changed', performSearchForMarkers);
@@ -104,4 +109,6 @@
 		return;
 	}
+	
+	
 	
 	_searchRunning = true;
@@ -145,4 +152,5 @@
     if(lngDelta == 0.1){lngDelta = 1; lngPrecision = 0; }
 	
+	/*
 	var query = "";
 	for(var i = 0; i <= Math.floor(latDistance / latDelta) + 1; i++)
@@ -183,4 +191,53 @@
 		}
 	}
+	*/
+	var query = "";
+	var iMax = Math.floor(latDistance / latDelta) + 1;
+	var jMax = Math.floor(lngDistance / lngDelta) + 1;;
+	for(var i = 0; i <= iMax; i++) //for(var i = 0; i <= Math.floor(latDistance / latDelta) + 1; i++)
+	{
+		for(var j = 0; j <= jMax; j++) //for(var j = 0; j <= Math.floor(lngDistance / lngDelta) + 1; j++)
+		{
+			//Some necessary variables
+			var newLat = neLat - (latDelta * i);
+			var newLatString = "" + newLat;
+			var newLatTrunc;
+			if(newLat < 0){newLatTrunc = Math.ceil(newLat);}
+			else{newLatTrunc = Math.floor(newLat);}
+			
+			var newLng = neLng - (lngDelta * j);
+			var newLngString = "" + newLng;
+			var newLngTrunc;
+			if(newLng < 0){newLngTrunc = Math.ceil(newLng);}
+			else{newLngTrunc = Math.floor(newLng);}
+
+			//Construct query
+			query += "(";
+			query += "CS:\"" + coordToAbsDirected(newLatTrunc, "lat");
+			//query += "CS:\"" + coordToAbsDirected(newLatTrunc, "lat") + "\" \"" + coordToAbsDirected(newLngTrunc, "lng") + "\""; //query += "LA:" + coordToAbsDirected(newLatTrunc, "lat");
+			if(latDelta != 1)
+			{ 
+				query += newLatString.substring(newLatString.indexOf(".") + 1, newLatString.indexOf(".") + latPrecision + 1);
+			}
+			query += " ";
+			//query += "+AND+";
+			
+			//query += "LN:" + coordToAbsDirected(newLngTrunc, "lng");
+			query += coordToAbsDirected(newLngTrunc, "lng");
+			if(lngDelta != 1)
+			{ 
+				query += newLngString.substring(newLngString.indexOf(".") + 1, newLngString.indexOf(".") + lngPrecision + 1);
+			}
+			query += "\"";			
+			query += ")";
+
+			//if(i != (Math.floor(latDistance / latDelta) + 1) || j != (Math.floor(lngDistance / lngDelta) + 1)){ query += "+OR+"; }
+			if(i != iMax || j != jMax){ query += "+OR+"; }
+		}
+	}
+	
+	// This works, why not from the double loop above?
+	//query = "(CS:\"" + coordToAbsDirected(newLatTrunc, "lat") + " " + coordToAbsDirected(newLngTrunc, "lng") + "\")";	
+	//alert("@@@@in map-scripts::performSearchForMarkers() - query: " + query);
 	
 	//var url = gs.xsltParams.library_name + "?a=q&s=RawQuery&rt=rd&c=" + gs.cgiParams.c + "&s1.rawquery=" + query + "&excerptid=jsonNodes";
@@ -196,4 +253,6 @@
 			var startIndex = responseText.indexOf(">");
 			var endIndex = responseText.indexOf("</");
+
+			console.log("@@@@ performSearch, got response: " + responseText);
 
 			var jsonNodes = eval(responseText.substring(startIndex+1, endIndex));
@@ -278,5 +337,11 @@
 		}
 
+		if(!doc.lat) {
+			var coordInfo = getLatLngForCoord(doc.coord);
+			bounds.extend(new google.maps.LatLng(coordInfo.lat, coordInfo.lng));
+		}
+		else {
  	        bounds.extend(new google.maps.LatLng(doc.lat, doc.lng));
+		}
 	}
 	
@@ -291,4 +356,25 @@
 }
 
+function getLatLngForCoord(coord) {
+	
+	// https://stackoverflow.com/questions/2559318/how-to-check-for-an-undefined-or-null-variable-in-javascript
+	if(!coord) {
+		 // some_variable is either null, undefined, 0, NaN, false, or an empty string
+		console.log("@@@@ In map-scripts::getLatLngForCoord(): no or invalid coord info");
+		return null;
+	}
+	
+	// coord is of the form: "37S77 157E53"
+	// lat will be 37S77, lng 157E53.
+	var indexOfSpace = coord.indexOf(" ");
+	if(indexOfSpace === -1) {
+		console.log("@@@@ In map-scripts::getLatLngForCoord(): bad format for coord  " + coord);
+		return null;
+	}
+	var latitude = coord.substring(0, indexOfSpace);
+	var longitude = coord.substring(indexOfSpace+1);
+	return {lat: latitude, lng: longitude}; // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Working_with_Objects
+}
+
 function loopThroughMarkers()
 {
@@ -363,4 +449,5 @@
 			gs.functions.setArchivesMetadata(collection, site_name, nodeID, "Latitude", null, lat, null, "override", function(){callbackFunction();});
 			gs.functions.setArchivesMetadata(collection, site_name, nodeID, "Longitude", null, lng, null, "override", function(){callbackFunction();});
+			gs.functions.setArchivesMetadata(collection, site_name, nodeID, "Coordinate", null, lat + " " + lng, null, "override", function(){callbackFunction();});
 			console.log("NodeID: " + nodeID);
 			console.log("GPS Click handler in collection:" + collection + " in site: " + site_name + " for Doc: " + nodeID + "(" + lat + "," + lng + ")");
@@ -376,5 +463,10 @@
 		clearInterval(_intervalHandle);
 		_intervalHandle = null;
-		_map.panTo(new google.maps.LatLng(doc.lat, doc.lng));
+		if(!doc.lat) {
+			var coordInfo = getLatLngForCoord(doc.coord);
+			_map.panTo(new google.maps.LatLng(coordInfo.lat, coordInfo.lng));
+		} else {
+			_map.panTo(new google.maps.LatLng(doc.lat, doc.lng));
+		}
 		clearAllInfoBoxes();
 		doc.marker.markerInfo.open(_map, doc.marker);
@@ -398,5 +490,12 @@
 function createMarker(doc, mainMarker)
 {
-	var pos = new google.maps.LatLng(doc.lat,doc.lng);
+	var pos;
+	if(doc.lat) {
+		pos = new google.maps.LatLng(doc.lat,doc.lng);
+	} else {
+		var coordInfo = getLatLngForCoord(doc.coord);			
+		pos = new google.maps.LatLng(coordInfo.lat,coordInfo.lng);
+	}
+	
 	
 	var docEdit = (("docEdit" in gs.cgiParams) && (gs.cgiParams['docEdit']));
@@ -525,4 +624,13 @@
 }
 
+function performDistanceSearchWithCoordinates(id, coord, degrees)
+{
+	var coordInfo = getLatLngForCoord(doc.coord);
+	if(!coordInfo) {
+		console.log("@@@ ERROR in map-scripts::performDistanceSearchWithCoordinates: coordInfo is null");		
+	}
+	performDistanceSearch(id, coordInfo.lat, coordInfo.lng, degrees);
+}
+
 function performDistanceSearch(id, lat, lng, degrees)
 {
Index: /main/trunk/greenstone3/web/interfaces/default/transform/map-tools.xsl
===================================================================
--- /main/trunk/greenstone3/web/interfaces/default/transform/map-tools.xsl	(revision 33124)
+++ /main/trunk/greenstone3/web/interfaces/default/transform/map-tools.xsl	(revision 33125)
@@ -12,5 +12,5 @@
     <td style="padding-left:5px; padding-right:5px;" valign="top">
       <a href="javascript:focusDocument('{@nodeID}');">
-	<img src="interfaces/default/images/map_marker.png"/>
+	<img src="interfaces/{$interface_name}/images/map_marker.png"/>
       </a>
     </td>
@@ -21,5 +21,5 @@
       <xsl:text>[</xsl:text>
       <xsl:for-each select="//documentNode">
-	<xsl:if test="metadataList/metadata[@name = 'Latitude'] and metadataList/metadata[@name = 'Longitude']">
+	<xsl:if test="(metadataList/metadata[@name = 'Latitude'] and metadataList/metadata[@name = 'Longitude']) or metadataList/metadata[@name = 'Coordinate']">
 	  <xsl:text>{</xsl:text>
 	  <xsl:text disable-output-escaping="yes">"nodeID":"</xsl:text>
@@ -29,9 +29,16 @@
 	  <xsl:value-of disable-output-escaping="yes" select="metadataList/metadata[@name = 'Title']"/>
 	  <xsl:text disable-output-escaping="yes">",</xsl:text>
-	  <xsl:text disable-output-escaping="yes">"lat":</xsl:text>
-	  <xsl:value-of disable-output-escaping="yes" select="metadataList/metadata[@name = 'Latitude']"/>
-	  <xsl:text>,</xsl:text>
-	  <xsl:text disable-output-escaping="yes">"lng":</xsl:text>
-	  <xsl:value-of disable-output-escaping="yes" select="metadataList/metadata[@name = 'Longitude']"/>
+	  <xsl:if test="metadataList/metadata[@name = 'Latitude'] and metadataList/metadata[@name = 'Longitude']">
+		  <xsl:text disable-output-escaping="yes">"lat":</xsl:text>
+		  <xsl:value-of disable-output-escaping="yes" select="metadataList/metadata[@name = 'Latitude']"/>
+		  <xsl:text>,</xsl:text>
+		  <xsl:text disable-output-escaping="yes">"lng":</xsl:text>
+		  <xsl:value-of disable-output-escaping="yes" select="metadataList/metadata[@name = 'Longitude']"/>
+	  </xsl:if>
+	  <xsl:if test="metadataList/metadata[@name = 'Coordinate']">
+		<xsl:text disable-output-escaping="yes">"coord":"</xsl:text>		
+		<xsl:value-of disable-output-escaping="yes" select="metadataList/metadata[@name = 'Coordinate']"/>
+		<xsl:text disable-output-escaping="yes">"</xsl:text>
+	  </xsl:if>
 	  <xsl:text>}</xsl:text>
 	  <xsl:if test="not(position() = count(//documentNode))">
@@ -46,4 +53,6 @@
     <gsf:metadata name="Latitude" hidden="true"/>
     <gsf:metadata name="Longitude" hidden="true"/>
+	<gsf:metadata name="Coordinate" hidden="true"/>
+	<gsf:metadata name="GPS.mapOverlay" hidden="true"/>
 <!--  these were included in version in query. don't think we need them...
     <gsf:metadata name="Image" hidden="true"/>
Index: /main/trunk/greenstone3/web/interfaces/default/transform/pages/classifier.xsl
===================================================================
--- /main/trunk/greenstone3/web/interfaces/default/transform/pages/classifier.xsl	(revision 33124)
+++ /main/trunk/greenstone3/web/interfaces/default/transform/pages/classifier.xsl	(revision 33125)
@@ -300,10 +300,10 @@
   <xsl:template name="documentNodePost">
     <xsl:if test="/page/pageResponse/format[@type='display' or @type='browse' or @type='search']/gsf:option[@name='mapEnabled']/@value = 'true'">
-      <xsl:if test="metadataList/metadata[@name='Latitude' or @name='Longitude']">
+      <xsl:if test="metadataList/metadata[@name='Latitude' or @name='Longitude' or @name='Coordinate']">
 	<xsl:call-template name="mapFeaturesIcon"/>
       </xsl:if>
     </xsl:if>
 
-
+	<!-- TODO: anything equivalent for Coordinate metadata? -->
     <xsl:if test="/page/pageResponse/format/gsf:option[@name='panoramaViewerEnabled']/@value = 'true'">
       <xsl:if test=" metadataList/metadata[@name = 'Latitude'] and metadataList/metadata[@name = 'Longitude'] and metadataList/metadata[@name = 'PhotoType']='Panorama'">
Index: /main/trunk/greenstone3/web/interfaces/default/transform/pages/document.xsl
===================================================================
--- /main/trunk/greenstone3/web/interfaces/default/transform/pages/document.xsl	(revision 33124)
+++ /main/trunk/greenstone3/web/interfaces/default/transform/pages/document.xsl	(revision 33125)
@@ -844,10 +844,16 @@
 				<xsl:when test="count(//documentNode) > 0">
 					<xsl:for-each select="//documentNode">
-						<xsl:if test="metadataList/metadata[@name = 'Latitude'] and metadataList/metadata[@name = 'Longitude']">
+						<xsl:if test="(metadataList/metadata[@name = 'Latitude'] and metadataList/metadata[@name = 'Longitude']) or metadataList/metadata[@name = 'Coordinate']">
 							<xsl:text>{</xsl:text>
 							<xsl:text disable-output-escaping="yes">"nodeID":"</xsl:text><xsl:value-of select="@nodeID"/><xsl:text disable-output-escaping="yes">",</xsl:text>
 							<xsl:text disable-output-escaping="yes">"title":"</xsl:text><xsl:value-of disable-output-escaping="yes" select="metadataList/metadata[@name = 'Title']"/><xsl:text disable-output-escaping="yes">",</xsl:text>
-							<xsl:text disable-output-escaping="yes">"lat":</xsl:text><xsl:value-of disable-output-escaping="yes" select="metadataList/metadata[@name = 'Latitude']"/><xsl:text>,</xsl:text>
-							<xsl:text disable-output-escaping="yes">"lng":</xsl:text><xsl:value-of disable-output-escaping="yes" select="metadataList/metadata[@name = 'Longitude']"/>
+							<xsl:if test="metadataList/metadata[@name = 'Latitude'] and metadataList/metadata[@name = 'Longitude']">
+								<xsl:text disable-output-escaping="yes">"lat":</xsl:text><xsl:value-of disable-output-escaping="yes" select="metadataList/metadata[@name = 'Latitude']"/><xsl:text>,</xsl:text>
+								<xsl:text disable-output-escaping="yes">"lng":</xsl:text><xsl:value-of disable-output-escaping="yes" select="metadataList/metadata[@name = 'Longitude']"/>
+							</xsl:if>
+							<xsl:if test="metadataList/metadata[@name = 'Coordinate']">
+								<xsl:text disable-output-escaping="yes">"coord":"</xsl:text><xsl:value-of disable-output-escaping="yes" select="metadataList/metadata[@name = 'Coordinate']"/>
+								<xsl:text disable-output-escaping="yes">"</xsl:text>
+							</xsl:if>
 							<xsl:text>}</xsl:text>
 							<xsl:if test="not(position() = count(//documentNode))">
@@ -860,10 +866,16 @@
 				<xsl:otherwise>
 					<xsl:for-each select="/page/pageResponse/document">
-						<xsl:if test="metadataList/metadata[@name = 'Latitude'] and metadataList/metadata[@name = 'Longitude']">
+						<xsl:if test="(metadataList/metadata[@name = 'Latitude'] and metadataList/metadata[@name = 'Longitude']) or metadataList/metadata[@name = 'Coordinate']">
 							<xsl:text>{</xsl:text>
 							<xsl:text disable-output-escaping="yes">"nodeID":"</xsl:text><xsl:value-of select="@selectedNode"/><xsl:text disable-output-escaping="yes">",</xsl:text>
 							<xsl:text disable-output-escaping="yes">"title":"</xsl:text><xsl:value-of disable-output-escaping="yes" select="metadataList/metadata[@name = 'Title']"/><xsl:text disable-output-escaping="yes">",</xsl:text>
-							<xsl:text disable-output-escaping="yes">"lat":</xsl:text><xsl:value-of disable-output-escaping="yes" select="metadataList/metadata[@name = 'Latitude']"/><xsl:text>,</xsl:text>
-							<xsl:text disable-output-escaping="yes">"lng":</xsl:text><xsl:value-of disable-output-escaping="yes" select="metadataList/metadata[@name = 'Longitude']"/>
+							<xsl:if test="metadataList/metadata[@name = 'Latitude'] and metadataList/metadata[@name = 'Longitude']">
+								<xsl:text disable-output-escaping="yes">"lat":</xsl:text><xsl:value-of disable-output-escaping="yes" select="metadataList/metadata[@name = 'Latitude']"/><xsl:text>,</xsl:text>
+								<xsl:text disable-output-escaping="yes">"lng":</xsl:text><xsl:value-of disable-output-escaping="yes" select="metadataList/metadata[@name = 'Longitude']"/>
+							</xsl:if>
+							<xsl:if test="metadataList/metadata[@name = 'Coordinate']">
+								<xsl:text disable-output-escaping="yes">"coord":"</xsl:text><xsl:value-of disable-output-escaping="yes" select="metadataList/metadata[@name = 'Coordinate']"/>
+								<xsl:text disable-output-escaping="yes">"</xsl:text>
+							</xsl:if>
 							<xsl:text>}</xsl:text>
 						</xsl:if>
@@ -893,4 +905,20 @@
 			</div>
 		</xsl:if>
+		
+		<xsl:if test="metadataList/metadata[@name = 'Coordinate']">
+			<div style="background:#BBFFBB; padding: 5px; margin:0px auto; width:890px;">
+				<xsl:value-of select="util:getInterfaceText($interface_name, /page/@lang, 'doc.map_nearby_docs')"/>
+				<img id="nearbyDocumentsToggle" style="margin-left:5px;" src="interfaces/{$interface_name}/images/expand.png">
+					<xsl:attribute name="onclick">
+						<xsl:text>performDistanceSearchWithCoordinates('</xsl:text>
+						<xsl:value-of select="@nodeID"/>
+						<xsl:text>', '</xsl:text>
+						<gsf:metadata name="Coordinate"/>
+						<xsl:text>', 2);</xsl:text>
+					</xsl:attribute>
+				</img>
+				<div id="nearbyDocuments"><xsl:text> </xsl:text></div>
+			</div>
+		</xsl:if>
 	</xsl:template>
 </xsl:stylesheet>
