Changeset 33128

Show
Ignore:
Timestamp:
06.06.2019 20:53:13 (11 days ago)
Author:
wy59
Message:

Improvements to Coordinate support AND bugfixes. BUT not all the fixes may be ideal, many marked with TODO. 1. Now we support an Array of coordinates. At present these are only displayed as Markers, but in future shapes should appear as shapes. 2. Bugfixes include: (a) expanding sections wasn't working when we had hierarchical docs with Coordinate data, because map-scripts 'overrode' the toggleSection function but no longer did any of the doc expanding behaviour that document_scripts.js used to do. This was not a problem with the ImagesGPS collection, simply because that did not have hierarchical/sectionalised documents. (b) Perl: A previous commit output duplicate Coordinates into the index. Now this doesn't happen. Fix works but may not be ideal. 3. Perl: (a) Reserved index names CD, CS for Coordinate and CoordShort?. Note however that LAT and LNG were never added to reserve list for index names. (b) Now doc.pm::processCoord() takes a section parameter and works out the section-ptr from that.

Location:
main/trunk
Files:
6 modified

Legend:

Unmodified
Added
Removed
  • main/trunk/greenstone2/perllib/doc.pm

    r33126 r33128  
    11381138         
    11391139        if($field =~ m/^(.+\.)?Longitude$/) { 
    1140             # if we are dealing with Longitude meta, we should 1. have Latitude meta; 2. already have processed Latitude meta 
     1140            # if we are dealing with Longitude meta, we should 1. have Latitude meta too; 2. already have processed Latitude meta 
    11411141            # in that case, add both Lat and Lng of this section as a Coordinate meta 
    11421142            my $latitude = $self->get_metadata_element ($section, "Latitude");           
    11431143            # TODO: would like all Longitude info together followed by all Coordinate info, but the following will add all coord info meta and end of this function will add Longitude meta 
    1144             $self->processCoordinate($section_ptr, $latitude, $value); # value is Longitude 
     1144            $self->processCoordinate($section, $latitude, $value); # value is Longitude 
    11451145        } 
    11461146    } 
    11471147 
    11481148    elsif($field eq "GPS.mapOverlay") { # then the value is a JSON string 
     1149     
     1150        # TODO: 
     1151        # If we already have Coordinate meta for this section of the document (as can happen during buildcol.pl), 
     1152        # let's ASSUME this means we've already processed GPS.mapOverlay meta into Coordinate meta for this section (can have happened during import.pl) 
     1153        # to avoid adding duplicate Coordinates meta, which then end up duplicated in the index 
     1154        # Of course, the assumption is not always true! We could have an image with embedded Lat and Lng meta, 
     1155        # and the same image doc's section could have GPS.mapOverlay meta (from shapes) added via the doc editor. 
     1156        # This very function would then have converted Lat/Lng into Coordinate meta (just in the if stmt above) and added it to the section. 
     1157        # And then by the time we process this section's GPS.mapOverlay meta here, we would notice the section has Coordinate meta already, 
     1158        # and therefore skip converting the GPS.mapOverlay meta into Coordinate meta! What to dooooo? 
     1159        # So the return statement immediately below is a temporary solution, until we find a better one that will always work. 
     1160        my $metaMap = $self->get_metadata_hashmap($section); 
     1161        if($metaMap->{'Coordinate'}) {  
     1162            return; 
     1163        } 
     1164         
    11491165        print STDERR "GPS.mapOverlay before val: " . $value . "\n"; 
    11501166         
     
    12141230                print STDERR "cos $centre_lat is $cos_lat\n"; 
    12151231 
    1216                 $self->processCoordinate($section_ptr, $lat_north, $lng_east); 
    1217                 $self->processCoordinate($section_ptr, $lat_south, $lng_east); 
    1218                 $self->processCoordinate($section_ptr, $lat_south, $lng_west); 
    1219                 $self->processCoordinate($section_ptr, $lat_north, $lng_west); 
     1232                $self->processCoordinate($section, $lat_north, $lng_east); 
     1233                $self->processCoordinate($section, $lat_south, $lng_east); 
     1234                $self->processCoordinate($section, $lat_south, $lng_west); 
     1235                $self->processCoordinate($section, $lat_north, $lng_west); 
    12201236             
    12211237            } 
     
    12231239                print STDERR "@@ MARKER FOUND WITH LAT: " . $shape->{"position"}->{"lat"} . "\n"; 
    12241240                print STDERR "@@ MARKER FOUND WITH LNG: " . $shape->{"position"}->{"lng"} . "\n"; 
    1225                 $self->processCoordinate($section_ptr, $shape->{"position"}->{"lat"}, $shape->{"position"}->{"lng"});                
     1241                $self->processCoordinate($section, $shape->{"position"}->{"lat"}, $shape->{"position"}->{"lng"});                
    12261242            } 
    12271243            elsif ($type eq "polyline" || $type eq "polygon") { 
    12281244                my $path_array = $shape->{"path"}; 
    12291245                foreach my $position (@$path_array) {                                    
    1230                     $self->processCoordinate($section_ptr, $position->{"lat"}, $position->{"lng"}); 
     1246                    $self->processCoordinate($section, $position->{"lat"}, $position->{"lng"}); 
    12311247                } 
    12321248            } 
     
    12351251                my $bounds = $shape->{"bounds"};                 
    12361252             
    1237                 $self->processCoordinate($section_ptr, $bounds->{"north"}, $bounds->{"east"}); 
    1238                 $self->processCoordinate($section_ptr, $bounds->{"south"}, $bounds->{"east"}); 
    1239                 $self->processCoordinate($section_ptr, $bounds->{"south"}, $bounds->{"west"}); 
    1240                 $self->processCoordinate($section_ptr, $bounds->{"north"}, $bounds->{"west"}); 
     1253                $self->processCoordinate($section, $bounds->{"north"}, $bounds->{"east"}); 
     1254                $self->processCoordinate($section, $bounds->{"south"}, $bounds->{"east"}); 
     1255                $self->processCoordinate($section, $bounds->{"south"}, $bounds->{"west"}); 
     1256                $self->processCoordinate($section, $bounds->{"north"}, $bounds->{"west"}); 
    12411257            }    
    12421258         
     
    12801296sub processCoordinate { 
    12811297    my $self = shift (@_); 
    1282     my ($section_ptr, $latitude, $longitude) = @_; 
     1298    my ($section, $latitude, $longitude) = @_; 
     1299 
     1300    my $section_ptr = $self->_lookup_section($section); 
    12831301 
    12841302    my $lat_direction = ($latitude =~ m/^-/) ? "S" : "N"; 
  • main/trunk/greenstone3/web/interfaces/default/js/classifier_scripts.js

    r33127 r33128  
    1111    } 
    1212    return false; 
     13} 
     14 
     15// TODO: Is there a better solution 
     16function _basicToggleSection(sectionID) { 
     17    // Leave this function here, even though it's empty. 
     18    // This function is here because: 
     19    // - it mirrors the identically named version in document_scripts 
     20    // - and this allows map_scripts to override it without knowing whether it's 
     21    //   overriding classifier_scripts::toggleSection() or document_scripts::toggleSection(). 
     22     
     23    // This method is not meant to call toggleSection. If anything it would be the other way around 
     24    // (as occurs in doc_scripts.js). But this method has to remain empty for classifier_scripts.js 
     25    // since map_scripts largely repeats classifier_scripts.js::toggleSection() code. 
    1326} 
    1427 
     
    111124    if(!inProgress[sectionID]) 
    112125    { 
    113         inProgress[sectionID] = true;        
     126        inProgress[sectionID] = true; 
    114127         
    115128        var sectionToggle = gs.jqGet("toggle" + sectionID); 
  • main/trunk/greenstone3/web/interfaces/default/js/document_scripts.js

    r33016 r33128  
    11/** Javascript file for viewing documents */ 
     2 
     3//-------TODO--------// 
     4// map-scripts.js needs these, but non-map viewing does not. Yet if we add these to map_scripts, 
     5// then in classifier mode, map_scripts will use classifier_scripts.js which already has these 
     6// So for now, we add them into this file for when map_scripts is in doc view mode and includes document_scripts.js. 
     7// It seems suboptimal, as these variables and function will be wasted when in regular non-map mode. 
     8// But unable to think of any other solution at present. 
     9var inProgress = new Array(); 
     10var openClassifiers = new Array(); 
     11var busy = false; 
     12 
     13 
     14 
     15function updateOpenClassifiers() 
     16{ 
     17    var oc = ""; 
     18    var first = true; 
     19    for(var key in openClassifiers) 
     20    { 
     21        if(first) 
     22        { 
     23            first = false; 
     24        } 
     25        else 
     26        { 
     27            oc += ","; 
     28        } 
     29         
     30        oc += key; 
     31    } 
     32     
     33    if(oc != undefined) 
     34    { 
     35        window.location.hash = oc; 
     36    } 
     37} 
     38 
     39//---------------// 
    240 
    341/** NOTE, this file uses inline templates which look for httpPath, assocfilepath, Source, Thumb, Title metadata. These need to be added into any xsl file that uses this javascript (using <gsf:metadata name="xx" hidden="true"/> if they are not already being collected. */ 
     
    66104    url += "&ck=" + gs.cgiParams.ck; 
    67105    } 
    68       
    69      
     106     
     107     
    70108     
    71109    $.ajax(url) 
     
    82120            } 
    83121             
    84             var text = response.substring(textStart, textEnd); 
     122            var text = response.substring(textStart, textEnd);           
    85123            callback(text); 
    86124        } 
     
    133171                return; 
    134172            } 
    135              
    136             var sections = response.substring(sectionsStart, sectionsEnd); 
    137             callback(sections); 
     173            else { 
     174                var sections = response.substring(sectionsStart, sectionsEnd); 
     175                callback(sections); 
     176            } 
    138177        } 
    139178        else 
     
    145184    { 
    146185        callback(null); 
    147     }); 
    148 } 
    149  
     186    });              
     187} 
     188 
     189// TODO: 
     190// DO NOT "MERGE" _basicToggleSection into toggleSection! 
     191// map_scripts.js calls _basicToggleSection as it redefines toggleSection() to do (more) stuff. 
    150192function toggleSection(sectionID, callback, tocDisabled) 
     193{ 
     194    _basicToggleSection(sectionID, callback, tocDisabled);   
     195} 
     196function _basicToggleSection(sectionID, callback, tocDisabled) 
    151197{ 
    152198    var docElem = gs.jqGet("doc" + sectionID); 
     
    173219            { 
    174220                if(text) 
    175                 {    
     221                {                    
    176222                    var nodeID = sectionID.replace(/\./g, "_"); 
    177223                    if(text.search("wrap" + nodeID) != -1) 
     
    193239                            if(callback) 
    194240                            { 
    195                                 callback(true); 
     241                                callback(true);                              
    196242                            } 
    197243                             
     
    219265                    } 
    220266                } 
    221             }); 
    222          
    223             docToggleElem.attr("src", gs.imageURLs.loading); 
     267            });      
     268             
     269            docToggleElem.attr("src", gs.imageURLs.loading);             
    224270        } 
    225271        else 
     
    310356{ 
    311357    expandAndExecute(sectionID, level, tocDisabled, function() 
    312             { 
     358            {                
    313359                var topVal = $(document.getElementById("doc" + sectionID)).offset().top - 50; 
    314360                $('html, body').stop().animate({scrollTop: topVal}, 1000); 
     
    332378    if(!level) 
    333379    { 
    334         level = 0; 
     380        level = 0;       
    335381    } 
    336382    var parts = sectionID.split("."); 
     
    360406        toggleSection(idToExpand, function(success) 
    361407        { 
    362             if(success) 
    363             { 
    364                 expandAndExecute(sectionID, level + 1, tocDisabled, executeAfter); 
    365             } 
    366         }, tocDisabled); 
     408                if(success) 
     409                { 
     410                    expandAndExecute(sectionID, level + 1, tocDisabled, executeAfter); 
     411                }            
     412            }, tocDisabled);         
    367413    } 
    368414    else 
     
    534580{ 
    535581    var docElem = gs.jqGet("doc" + sectionID); 
    536     if(docElem.css("display") == "block") 
     582     
     583    if(docElem.css("display") === "block") 
    537584    { 
    538585        return true; 
  • main/trunk/greenstone3/web/interfaces/default/js/map-scripts.js

    r33127 r33128  
    2424    if(jsonNodeDiv.length) 
    2525    { 
    26         console.log("@@@ JSON node div html: " + jsonNodeDiv.html()); 
     26        //console.log("@@@ JSON node div html: " + jsonNodeDiv.html()); 
    2727        var jsonNodes = eval(jsonNodeDiv.html()); 
    2828         
     
    3232            { 
    3333                _docList[jsonNodes[i].nodeID] = jsonNodes[i]; 
    34                 _docList.ids.push(jsonNodes[i].nodeID); 
    35                 console.log("@@@ JSON node: " + jsonNodes[i]); 
    36                 createMarker(jsonNodes[i], true); 
     34                _docList.ids.push(jsonNodes[i].nodeID);              
     35                createMarkers(jsonNodes[i], true); 
    3736            } 
    3837            updateMap(); 
     
    4039        else 
    4140        { 
     41            //hiding the map 
    4242            //$("#map_canvas").css({visibility:"hidden", height:"0px"}); 
    43             $("#map_canvas").css({visibility:"hidden"}); 
    44             //console.log("suppressing hiding the map"); 
     43            $("#map_canvas").css({visibility:"hidden"}); // if you comment this out, add a log message saying "suppressing hiding map" 
    4544        } 
    4645    } 
     
    9796     
    9897    if ($map_canvas.length > 0) { 
    99         console.log("### map-scripts::setUpMap: map_canvas.exists"); 
    10098        _map = new google.maps.Map($map_canvas[0], myOptions); 
    10199        google.maps.event.addListener(_map, 'bounds_changed', performSearchForMarkers); 
     
    254252            var endIndex = responseText.indexOf("</"); 
    255253 
    256             console.log("@@@@ performSearch, got response: " + responseText); 
     254            //console.log("@@@@ performSearch, got response: " + responseText); 
    257255 
    258256            var jsonNodes = eval(responseText.substring(startIndex+1, endIndex)); 
     
    271269                        _docList.ids.push(doc.nodeID); 
    272270 
    273                         createMarker(doc, false); 
     271                        createMarkers(doc, false); 
    274272                    } 
    275273                } 
     
    337335        } 
    338336 
    339         if(doc.coord) { 
    340             var coordInfo = getLatLngForCoord(doc.coord); 
    341             bounds.extend(new google.maps.LatLng(coordInfo.lat, coordInfo.lng)); 
     337         
     338        if(doc.coords) { 
     339            for(var x = 0; x < doc.coords.length; x++) { 
     340                var coord = doc.coords[x]; 
     341                var coordInfo = getLatLngForCoord(doc.coords[x]); 
     342                bounds.extend(new google.maps.LatLng(coordInfo.lat, coordInfo.lng)); 
     343            } 
    342344        } 
    343345        else { 
     
    463465        clearInterval(_intervalHandle); 
    464466        _intervalHandle = null; 
    465         if(doc.coord) { 
    466             var coordInfo = getLatLngForCoord(doc.coord); 
    467             _map.panTo(new google.maps.LatLng(coordInfo.lat, coordInfo.lng)); 
     467        if(doc.coords) { 
     468            for(var x = 0; x < doc.coords.length; x++) { 
     469                var coord = doc.coords[x]; 
     470                var coordInfo = getLatLngForCoord(doc.coords[x]); 
     471                _map.panTo(new google.maps.LatLng(coordInfo.lat, coordInfo.lng)); 
     472            } 
    468473        } else { 
    469474            _map.panTo(new google.maps.LatLng(doc.lat, doc.lng)); 
     
    488493} 
    489494 
    490 function createMarker(doc, mainMarker) 
    491 { 
    492     var pos; 
    493     if(doc.coord) { 
    494         var coordInfo = getLatLngForCoord(doc.coord);            
    495         pos = new google.maps.LatLng(coordInfo.lat,coordInfo.lng);       
     495function createMarkers(doc, mainMarker) { 
     496    if(doc.coords) { 
     497        for(var x = 0; x < doc.coords.length; x++) { 
     498            var coord = doc.coords[x]; 
     499            var coordInfo = getLatLngForCoord(doc.coords[x]); 
     500            pos = new google.maps.LatLng(coordInfo.lat,coordInfo.lng);           
     501            createMarker(doc, pos, mainMarker); 
     502        } 
    496503    } else { 
    497504        pos = new google.maps.LatLng(doc.lat,doc.lng); 
    498     } 
    499      
    500      
     505        createMarker(doc, pos, mainMarker); 
     506    } 
     507} 
     508 
     509 
     510// Param mainMarker: if set to true, marker is red. If false, marker is blue 
     511function createMarker(doc, pos, mainMarker) 
     512{ 
    501513    var docEdit = (("docEdit" in gs.cgiParams) && (gs.cgiParams['docEdit'])); 
    502514    //var draggable_val = (docEdit) ? true : false; 
     
    609621                _docList.ids.push(doc.nodeID); 
    610622 
    611                 createMarker(doc, false); 
     623                createMarkers(doc, false); 
    612624            } 
    613625             
     
    825837function modifyFunctions() 
    826838{ 
    827     toggleSection = function(sectionID) 
    828     { 
     839    // This function "overrides" toggleSection in both classifier_scripts.js and document_scripts.js 
     840    // However, classifier_scripts.js::toggleSection() only took one parameter, sectionID, whereas 
     841    // document_scripts.js::toggleSection() took 3 params (sectionID, callback, tocDisabled). 
     842    // So to be compatible with both, need map-scripts::toggleSection() here to support all 3 in that order. 
     843    toggleSection = function(sectionID, callback, tocDisabled) 
     844    { 
     845        _basicToggleSection(sectionID, callback, tocDisabled); 
     846         
    829847        var section = gs.jqGet("div" + sectionID); 
    830         var sectionToggle = gs.jqGet("toggle" + sectionID); 
    831          
     848        var sectionToggle = gs.jqGet("toggle" + sectionID);      
     849                 
    832850        if(sectionToggle == undefined) 
    833         { 
     851        {            
    834852            return; 
    835         } 
     853        }        
    836854         
    837855        // Test if 'section' exists.   
     
    839857        // http://stackoverflow.com/questions/920236/how-can-i-detect-if-a-selector-returns-null 
    840858        if(section.length !== 0) 
    841         {            
     859        {                
    842860            if(isExpanded(sectionID)) 
    843861            { 
     
    862880        { 
    863881            httpRequest(sectionID); 
    864         } 
     882        }        
     883         
    865884    } 
    866885     
     
    901920                    checkout(); 
    902921                } 
     922                /*else if(gs.cgiParams.documentbasket == "on") // TODO: copied from classifier_scripts.js - should this else block be included here (and happen when mapEnabled) or not? 
     923                { 
     924                    dmcheckout(); 
     925                }*/ 
    903926                updateOpenClassifiers(); 
    904927                getSubClassifier(sectionID); 
  • main/trunk/greenstone3/web/interfaces/default/transform/map-tools.xsl

    r33126 r33128  
    3939      <xsl:if test="metadataList/metadata[@name = 'Coordinate']"> 
    4040        <xsl:text disable-output-escaping="yes">,</xsl:text> 
    41         <xsl:text disable-output-escaping="yes">"coord":"</xsl:text>         
    42         <xsl:value-of disable-output-escaping="yes" select="metadataList/metadata[@name = 'Coordinate']"/> 
    43         <xsl:text disable-output-escaping="yes">"</xsl:text> 
     41        <xsl:text disable-output-escaping="yes">"coords":</xsl:text> 
     42        <xsl:text>[</xsl:text> 
     43        <xsl:for-each select="metadataList/metadata[@name = 'Coordinate']"> 
     44            <xsl:text disable-output-escaping="yes">"</xsl:text> 
     45            <xsl:value-of disable-output-escaping="yes" select="current()"/> 
     46            <xsl:text disable-output-escaping="yes">"</xsl:text> 
     47            <xsl:text disable-output-escaping="yes">,</xsl:text> 
     48        </xsl:for-each> 
     49        <xsl:text>]</xsl:text> 
    4450      </xsl:if> 
    4551      <xsl:text>}</xsl:text> 
  • main/trunk/greenstone3/web/interfaces/default/transform/pages/document.xsl

    r33126 r33128  
    140140            <xsl:if test="not(/page/pageResponse/format[@type='display' or @type='browse' or @type='search']/gsf:option[@name='sectionExpandCollapse']/@value) or /page/pageResponse/format[@type='display' or @type='browse' or @type='search']/gsf:option[@name='sectionExpandCollapse']/@value = 'true'"> 
    141141                <td class="headerTD"> 
    142                     <img id="dtoggle{@nodeID}" onclick="toggleSection('{@nodeID}');" class="icon">           
     142                    <img id="dtoggle{@nodeID}" onclick="toggleSection('{@nodeID}');" class="icon"> 
    143143                        <xsl:attribute name="src"> 
    144144                            <xsl:choose> 
     
    856856                            <xsl:if test="metadataList/metadata[@name = 'Coordinate']"> 
    857857                                <xsl:text disable-output-escaping="yes">,</xsl:text> 
    858                                 <xsl:text disable-output-escaping="yes">"coord":"</xsl:text><xsl:value-of disable-output-escaping="yes" select="metadataList/metadata[@name = 'Coordinate']"/> 
    859                                 <xsl:text disable-output-escaping="yes">"</xsl:text> 
     858                                <xsl:text disable-output-escaping="yes">"coords":</xsl:text> 
     859                                <xsl:text>[</xsl:text> 
     860                                <xsl:for-each select="metadataList/metadata[@name = 'Coordinate']"> 
     861                                    <xsl:text disable-output-escaping="yes">"</xsl:text> 
     862                                    <xsl:value-of disable-output-escaping="yes" select="current()"/> 
     863                                    <xsl:text disable-output-escaping="yes">"</xsl:text> 
     864                                    <xsl:text disable-output-escaping="yes">,</xsl:text> 
     865                                </xsl:for-each> 
     866                                <xsl:text>]</xsl:text> 
    860867                            </xsl:if> 
    861868                            <xsl:text>}</xsl:text> 
     
    881888                            <xsl:if test="metadataList/metadata[@name = 'Coordinate']"> 
    882889                                <xsl:text disable-output-escaping="yes">,</xsl:text> 
    883                                 <xsl:text disable-output-escaping="yes">"coord":"</xsl:text><xsl:value-of disable-output-escaping="yes" select="metadataList/metadata[@name = 'Coordinate']"/> 
    884                                 <xsl:text disable-output-escaping="yes">"</xsl:text> 
     890                                <xsl:text disable-output-escaping="yes">"coords":</xsl:text> 
     891                                <xsl:text>[</xsl:text> 
     892                                <xsl:for-each select="metadataList/metadata[@name = 'Coordinate']"> 
     893                                    <xsl:text disable-output-escaping="yes">"</xsl:text> 
     894                                    <xsl:value-of disable-output-escaping="yes" select="current()"/> 
     895                                    <xsl:text disable-output-escaping="yes">"</xsl:text> 
     896                                    <xsl:text disable-output-escaping="yes">,</xsl:text> 
     897                                </xsl:for-each> 
     898                                <xsl:text>]</xsl:text> 
    885899                            </xsl:if> 
    886900                            <xsl:text>}</xsl:text> 
     
    891905            <xsl:text>]</xsl:text> 
    892906        </div> 
     907         
     908        <!-- TODO: Why do we have to do this to see Coordinate appear in extraMetadataList on o=xml page, when Lat and Lng appear without doing the same??? --> 
     909        <gsf:metadata name="Coordinate" hidden="true"/> 
    893910    </xsl:template> 
    894911     
     
    914931        <xsl:if test="metadataList/metadata[@name = 'Coordinate']"> 
    915932            <div style="background:#BBFFBB; padding: 5px; margin:0px auto; width:890px;"> 
    916                 <xsl:value-of select="util:getInterfaceText($interface_name, /page/@lang, 'doc.map_nearby_docs')"/> 
    917                 <img id="nearbyDocumentsToggle" style="margin-left:5px;" src="interfaces/{$interface_name}/images/expand.png"> 
    918                     <xsl:attribute name="onclick"> 
    919                         <xsl:text>performDistanceSearchWithCoordinates('</xsl:text> 
    920                         <xsl:value-of select="@nodeID"/> 
    921                         <xsl:text>', '</xsl:text> 
    922                         <gsf:metadata name="Coordinate"/> 
    923                         <xsl:text>', 2);</xsl:text> 
    924                     </xsl:attribute> 
    925                 </img> 
    926                 <div id="nearbyDocuments"><xsl:text> </xsl:text></div> 
     933            <xsl:value-of select="util:getInterfaceText($interface_name, /page/@lang, 'doc.map_nearby_docs')"/> 
     934            <xsl:for-each select="metadataList/metadata[@name = 'Coordinate']"> 
     935             
     936                <xsl:variable name="coordinate"><xsl:value-of select="current()"/></xsl:variable> 
     937             
     938                 
     939                    <img id="nearbyDocumentsToggle" style="margin-left:5px;" src="interfaces/{$interface_name}/images/expand.png"> 
     940                        <xsl:attribute name="onclick"> 
     941                            <xsl:text>performDistanceSearchWithCoordinates('</xsl:text> 
     942                            <xsl:value-of select="@nodeID"/> 
     943                            <xsl:text>', '</xsl:text> 
     944                            <xsl:value-of select="$coordinate"/><!--<gsf:metadata name="Coordinate"/>--> 
     945                            <xsl:text>', 2);</xsl:text> 
     946                        </xsl:attribute> 
     947                    </img>                   
     948            </xsl:for-each>  
     949            <div id="nearbyDocuments"><xsl:text> </xsl:text></div>               
    927950            </div> 
    928951        </xsl:if>