Show
Ignore:
Timestamp:
07.06.2019 20:30:54 (6 months ago)
Author:
wy59
Message:

1. Moved from plotting markers for each coord in doc.coords array to creating doc.mapOverlay from GPS.mapOverlay meta and converting each shape therein into Google Map Shapes/Overlays and storing these in the new doc.shapes array. 2. We now use Google Map InfoWindows? to display label information for shapes/markers that have them. For now the labels are displayed/hidden on mouseover and mouseout. We can make them permanently displayed if necessary. 3. Lots more TODO questions added.

Location:
main/trunk/greenstone3/web/interfaces/default
Files:
5 modified

Legend:

Unmodified
Added
Removed
  • main/trunk/greenstone3/web/interfaces/default/js/map-scripts-shapes-util.js

    r33085 r33140  
    219219    var NE = new google.maps.LatLng(north, east); 
    220220    var SW = new google.maps.LatLng(south, west); 
    221     bounds = new google.maps.LatLngBounds(SW, NE); 
     221    bounds = new google.maps.LatLngBounds(SW, NE); // THIS IS NOT IN GOOGLE MAPS' RECTANGLE FORMAT! 
    222222     
    223223    var rect = ShapesUtil._createRectangle(json_rect,bounds); 
     
    485485 
    486486 
     487// function returns an object (representing a Coordinate) of the form {lat: 34.052, lng: -118.243} 
     488// For each shape's properties: https://developers.google.com/maps/documentation/javascript/shapes 
     489ShapesUtil.getLabelCoordinate = function(shape) {    
     490     
     491    if (shape.type === google.maps.drawing.OverlayType.POLYLINE) { 
     492        var path = shape.getPath(); // assuming a minimum of one path array for each polygon 
     493        return path.getAt(0); // return the first coord of polyline for now 
     494    } else if (shape.type === google.maps.drawing.OverlayType.POLYGON) { 
     495        var path = shape.getPath(); // assuming a minimum of one path array for each polygon 
     496        return path.getAt(0); // return the first coord for now 
     497    } else if (shape.type === google.maps.drawing.OverlayType.RECTANGLE) {       
     498        // Doesn't work: 
     499        //var latitude = (shape.bounds.north + shape.bounds.south) / 2; 
     500        //var longitude = (shape.bounds.east + shape.bounds.west) / 2; 
     501        //console.log("Rect: " + shape.bounds.toString()); 
     502        //return {lat: shape.bounds.north, lng: shape.bounds.east}; 
     503        // A Google Maps Rectangle's bounds property has 4 attributes/properties: north, south, east, west 
     504        // But this ShapesUtil.Rectangle class's bounds property has 2 coord properties: SW and NE. 
     505        // However, it is handy in this case, since we can just call getCenter() 
     506        return shape.bounds.getCenter(); 
     507    } else if (shape.type === google.maps.drawing.OverlayType.CIRCLE) {      
     508        return shape.center; // circles have a centre 
     509    } else if (shape.type === google.maps.drawing.OverlayType.MARKER){ 
     510        return shape.position; 
     511    } 
     512    else { 
     513        console.error("*** ShapesUtil::getLabelCoordinate() Unrecognized shape type: " +shape.type); 
     514        return null; 
     515    } 
     516} 
     517 
     518 
  • main/trunk/greenstone3/web/interfaces/default/js/map-scripts.js

    r33130 r33140  
    326326        if(doc.parentCL && doc.parentCL.style.display == "none") 
    327327        { 
    328             doc.marker.setVisible(false); 
     328            if(doc.shapes) { 
     329                for(var x = 0; x < doc.shapes.length; x++) { 
     330                    doc.shapes[x].setVisible(false); 
     331                } 
     332            } else { 
     333                doc.marker.setVisible(false); 
     334            } 
    329335            continue; 
    330336        } 
    331337        else 
    332338        { 
    333             doc.marker.setVisible(true); 
    334             markersOnMap++; 
     339            if(doc.shapes) { 
     340                for(var x = 0; x < doc.shapes.length; x++) { 
     341                    doc.shapes[x].setVisible(true); 
     342                } 
     343            } else { 
     344                doc.marker.setVisible(true); 
     345            } 
     346            markersOnMap++; // TODO: what do we do with this when we have shapes. This variable may be connected with centring the map? 
    335347        } 
    336348 
     
    424436} 
    425437 
    426 function attachClickHandler(marker, nodeID) 
     438// Unused at present, called by draggableCreateMarker 
     439// Map used to have editable markers. Now editable markers are restricted to the map-editor. 
     440function attachDraggableClickHandler(marker, nodeID) 
    427441{    
    428442    google.maps.event.addListener(marker, 'click', function() 
     
    493507} 
    494508 
    495 function 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         } 
    503     } else { 
     509function createMarkers(doc, mainMarker) {    
     510    if(doc.mapoverlay) { 
     511        //console.log("Have shapes: " + doc.mapoverlay.toString()); 
     512        createShapes(doc, mainMarker); 
     513    } else { // backwards compatible to deal with Lat and Lng meta stored for doc 
    504514        pos = new google.maps.LatLng(doc.lat,doc.lng); 
    505515        createMarker(doc, pos, mainMarker); 
     
    507517} 
    508518 
    509  
     519function addInfoMarker(doc, shape) { 
     520     
     521    if(!shape.description) { 
     522        //console.log("@@@@ " + shape.type.toString() + " had no description/label"); 
     523        return; 
     524    } 
     525     
     526    // else add an InfoWindow for this shape using the label (shape.description) 
     527     
     528    // https://developers.google.com/maps/documentation/javascript/infowindows 
     529    // An InfoWindow's "position contains the LatLng at which this info window is anchored. 
     530    // Note: An InfoWindow may be attached either to a Marker object (in which case its position is based on the marker's location) 
     531    // or on the map itself at a specified LatLng. Opening an info window on a marker will automatically update the position." 
     532    var infoWindow = new google.maps.InfoWindow({content:shape.description}); // NOTE: if not setting content or position properties 
     533            // inside this constructor, need to call setContent/setPosition to set them 
     534     
     535    if(shape.type === google.maps.drawing.OverlayType.MARKER) { 
     536        var marker = shape; 
     537        //marker.addListener('mouseover', function() { 
     538          infoWindow.open(_map, marker); 
     539        //}); 
     540        attachClickHandler(marker, doc.nodeID); // do what the original code used to do here 
     541    } 
     542    else { 
     543        var coord = ShapesUtil.getLabelCoordinate(shape);        
     544        console.log("Coord for " + shape.type.toString() + " is " + coord.toString()); 
     545        infoWindow.setPosition(coord); 
     546        shape.addListener('mouseover', function() { 
     547            infoWindow.open(_map); 
     548        }); 
     549        shape.addListener('mouseout', function() { 
     550            infoWindow.close(); 
     551        }); 
     552        attachClickHandler(shape, doc.nodeID); // as above       
     553    } 
     554} 
     555 
     556// This function will create Google Shapes/Overlays and markers out of a given doc JSONNode's doc.mapOverlay 
     557// (doc.mapOverlay shapes are stored as an array of JSON) and store the shapes/overlays in the doc.shapes array. 
     558// Note: doc.coords are just an array of all the coordinates in a doc, not indicating to which shapes they belong. 
     559// They're only **for searching** - for seaching which coords (hence docs) are in a map. 
     560// Param mainMarker: if set to true, marker is red. If false, marker is blue 
     561function createShapes(doc, mainMarker) 
     562{    
     563    // for doc.shapes: don't store JSON anymore, convert them to google Shapes overlays and store them instead 
     564    doc.shapes = []; 
     565    for (var i=0; i<doc.mapoverlay.length; i++) { 
     566        var shape = ShapesUtil.JSONToShape(doc.mapoverlay[i]);       
     567        doc.shapes[i] = shape;       
     568        shape.setMap(_map); 
     569        shape["title"] = doc.title; 
     570         
     571        // Unset editable and draggable properties of shape 
     572        // And for markers, which are initialised to clickable besides, undo the clickability 
     573        // and set them  
     574        if(shape.type === google.maps.drawing.OverlayType.MARKER) { 
     575            var marker = shape; 
     576            // mainMarkers should be red 
     577            if(!mainMarker) { 
     578                marker["icon"] = "interfaces/" + gs.xsltParams.interface_name + "/images/bluemarker.png"; 
     579            } 
     580            marker.clickable = false; // only markers 
     581        } 
     582         
     583        shape.editable = false; 
     584        shape.draggable = false; 
     585         
     586         
     587         
     588        // doc[i]'s label = doc.shapes[i].description 
     589        addInfoMarker(doc, shape); 
     590    }    
     591     
     592    var docElement = gs.jqGet("div" + doc.nodeID); 
     593    var parent; 
     594    if(docElement) 
     595    { 
     596        parent = docElement.parentNode; 
     597    } 
     598 
     599    while(parent && parent.nodeName != "BODY") 
     600    { 
     601        if($(parent).attr("id") && $(parent).attr("id").search("divCL") != -1) 
     602        { 
     603            doc.parentCL = parent; 
     604            break; 
     605        } 
     606         
     607        parent = parent.parentNode; 
     608    } 
     609} 
     610 
     611// This method is only for backwards compatibility: for those collections with docs that only have Lat and Lng meta 
     612// and no GPS.mapOverlay (and hence Coordinate) meta. 
    510613// Param mainMarker: if set to true, marker is red. If false, marker is blue 
    511614function createMarker(doc, pos, mainMarker) 
     615{ 
     616    var marker; 
     617    if(mainMarker) 
     618    { 
     619        marker = new google.maps.Marker 
     620        ({ 
     621            position: pos, 
     622            title:doc.title, 
     623            map:_map 
     624        }); 
     625    } 
     626    else 
     627    { 
     628        marker = new google.maps.Marker 
     629        ({ 
     630            position: pos, 
     631            title:doc.title, 
     632            map:_map, 
     633            icon:"interfaces/" + gs.xsltParams.interface_name + "/images/bluemarker.png" 
     634        }); 
     635    } 
     636 
     637    var docElement = gs.jqGet("div" + doc.nodeID); 
     638    var parent; 
     639    if(docElement) 
     640    { 
     641        parent = docElement.parentNode; 
     642    } 
     643 
     644    while(parent && parent.nodeName != "BODY") 
     645    { 
     646        if($(parent).attr("id") && $(parent).attr("id").search("divCL") != -1) 
     647        { 
     648            doc.parentCL = parent; 
     649            break; 
     650        } 
     651         
     652        parent = parent.parentNode; 
     653    } 
     654 
     655    var info = new google.maps.InfoWindow({content:doc.title}); 
     656    marker.markerInfo = info; 
     657    doc.marker = marker; 
     658    attachClickHandler(marker, doc.nodeID); 
     659} 
     660 
     661// TODO: with the following, it seems that clicking on shape expands the entire document 
     662// Should it be that clicking on a shape should expand the doc section that contains that shape meta? 
     663function attachClickHandler(shapeOrMarker, nodeID) 
     664{ 
     665    google.maps.event.addListener(shapeOrMarker, 'click', function() 
     666    { 
     667        document.location.href = gs.xsltParams.library_name + "?a=d&ed=1&c=" + gs.cgiParams.c + "&d=" + nodeID + "&dt=hierarchy&p.a=b&p.sa=&p.s=ClassifierBrowse"; 
     668    }); 
     669} 
     670 
     671// TODO: 
     672// Version of createMarker function containing Zeddy's modifications (pre-mapeditor?) to make markers 
     673// on the public *map* (not on map-editor) draggable/editable and to save these edits/rebuild with them. 
     674// Do we want to continue supporting editing on the main map? I thought we weren't going to and that editing 
     675// was exclusive to the map-editor, with the public map only displaying the saved features? 
     676function draggableCreateMarker(doc, pos, mainMarker) 
    512677{ 
    513678    var docEdit = (("docEdit" in gs.cgiParams) && (gs.cgiParams['docEdit'])); 
     
    522687    var draggable_val = (!docEdit || loggedOutVar) ? false : true; 
    523688     
    524     var marker 
     689    var marker; 
    525690    if(mainMarker) 
    526691    { 
     
    566731    marker.markerInfo = info; 
    567732    doc.marker = marker; 
    568     attachClickHandler(marker, doc.nodeID); 
     733    attachDraggableClickHandler(marker, doc.nodeID); 
    569734 
    570735    ////////////////////////////////////////////////////// TEST 
  • main/trunk/greenstone3/web/interfaces/default/transform/layouts/header.xsl

    r33124 r33140  
    748748  <xsl:template name="map-scripts"> 
    749749    <meta content="initial-scale=1.0, user-scalable=no" name="viewport"/> 
    750     <script src="http://maps.googleapis.com/maps/api/js?key=AIzaSyCofVTps3xHfMvIcTMHqYMMxe3xXfkAxnI&amp;libraries=drawing" type="text/javascript"><xsl:text> </xsl:text></script>    
     750    <script src="http://maps.googleapis.com/maps/api/js?key=AIzaSyCofVTps3xHfMvIcTMHqYMMxe3xXfkAxnI&amp;libraries=drawing" type="text/javascript"><xsl:text> </xsl:text></script> 
     751    <script src="interfaces/{$interface_name}/js/map-scripts-shapes-util.js" type="text/javascript"><xsl:text> </xsl:text></script> 
    751752    <script src="interfaces/{$interface_name}/js/map-scripts.js" type="text/javascript"><xsl:text> </xsl:text></script> 
    752753    <script type="text/javascript">$(window).load(initializeMapScripts);</script> 
  • main/trunk/greenstone3/web/interfaces/default/transform/map-tools.xsl

    r33128 r33140  
    2121      <xsl:text>[</xsl:text> 
    2222      <xsl:for-each select="//documentNode"> 
    23     <xsl:if test="(metadataList/metadata[@name = 'Latitude'] and metadataList/metadata[@name = 'Longitude']) or metadataList/metadata[@name = 'Coordinate']"> 
     23    <xsl:if test="(metadataList/metadata[@name = 'Latitude'] and metadataList/metadata[@name = 'Longitude']) or metadataList/metadata[@name = 'Coordinate'] or metadataList/metadata[@name = 'GPS.mapOverlay']"> 
    2424      <xsl:text>{</xsl:text> 
    2525      <xsl:text disable-output-escaping="yes">"nodeID":"</xsl:text> 
     
    4949        <xsl:text>]</xsl:text> 
    5050      </xsl:if> 
     51       
     52      <xsl:if test="metadataList/metadata[@name = 'GPS.mapOverlay']"> 
     53        <xsl:text disable-output-escaping="yes">,</xsl:text> 
     54        <xsl:text disable-output-escaping="yes">"mapoverlay":</xsl:text> 
     55        <xsl:value-of disable-output-escaping="yes" select="metadataList/metadata[@name = 'GPS.mapOverlay']"/> 
     56      </xsl:if> 
     57                             
    5158      <xsl:text>}</xsl:text> 
    5259      <xsl:if test="not(position() = count(//documentNode))"> 
  • main/trunk/greenstone3/web/interfaces/default/transform/pages/document.xsl

    r33128 r33140  
    844844                <xsl:when test="count(//documentNode) > 0"> 
    845845                    <xsl:for-each select="//documentNode"> 
    846                         <xsl:if test="(metadataList/metadata[@name = 'Latitude'] and metadataList/metadata[@name = 'Longitude']) or metadataList/metadata[@name = 'Coordinate']"> 
     846                        <xsl:if test="(metadataList/metadata[@name = 'Latitude'] and metadataList/metadata[@name = 'Longitude']) or metadataList/metadata[@name = 'Coordinate'] or metadataList/metadata[@name = 'GPS.mapOverlay']"> 
    847847                            <xsl:text>{</xsl:text> 
    848848                            <xsl:text disable-output-escaping="yes">"nodeID":"</xsl:text><xsl:value-of select="@nodeID"/><xsl:text disable-output-escaping="yes">",</xsl:text> 
     
    862862                                    <xsl:value-of disable-output-escaping="yes" select="current()"/> 
    863863                                    <xsl:text disable-output-escaping="yes">"</xsl:text> 
     864                                    <!--<xsl:if test="not(position() = count(metadataList/metadata[@name = 'Coordinate'])"> 
     865                                        <xsl:text>,</xsl:text> 
     866                                    </xsl:if>                
     867                                    --> 
    864868                                    <xsl:text disable-output-escaping="yes">,</xsl:text> 
    865869                                </xsl:for-each> 
    866870                                <xsl:text>]</xsl:text> 
     871                            </xsl:if>                        
     872                             
     873                            <xsl:if test="metadataList/metadata[@name = 'GPS.mapOverlay']"> 
     874                                <xsl:text disable-output-escaping="yes">,</xsl:text> 
     875                                <xsl:text disable-output-escaping="yes">"mapoverlay":</xsl:text> 
     876                                <xsl:value-of disable-output-escaping="yes" select="metadataList/metadata[@name = 'GPS.mapOverlay']"/> 
    867877                            </xsl:if> 
     878                             
    868879                            <xsl:text>}</xsl:text> 
     880                             
    869881                            <xsl:if test="not(position() = count(//documentNode))"> 
    870882                                <xsl:text>,</xsl:text> 
    871883                            </xsl:if> 
     884                             
    872885                        </xsl:if> 
    873886                    </xsl:for-each> 
     
    876889                <xsl:otherwise> 
    877890                    <xsl:for-each select="/page/pageResponse/document"> 
    878                         <xsl:if test="(metadataList/metadata[@name = 'Latitude'] and metadataList/metadata[@name = 'Longitude']) or metadataList/metadata[@name = 'Coordinate']"> 
     891                        <xsl:if test="(metadataList/metadata[@name = 'Latitude'] and metadataList/metadata[@name = 'Longitude']) or metadataList/metadata[@name = 'Coordinate']  or metadataList/metadata[@name = 'GPS.mapOverlay']"> 
    879892                            <xsl:text>{</xsl:text> 
    880893                            <xsl:text disable-output-escaping="yes">"nodeID":"</xsl:text><xsl:value-of select="@selectedNode"/><xsl:text disable-output-escaping="yes">",</xsl:text> 
     
    898911                                <xsl:text>]</xsl:text> 
    899912                            </xsl:if> 
     913                             
     914                            <xsl:if test="metadataList/metadata[@name = 'GPS.mapOverlay']"> 
     915                                <xsl:text disable-output-escaping="yes">,</xsl:text> 
     916                                <xsl:text disable-output-escaping="yes">"mapoverlay":</xsl:text> 
     917                                <xsl:value-of disable-output-escaping="yes" select="metadataList/metadata[@name = 'GPS.mapOverlay']"/> 
     918                            </xsl:if> 
     919                             
    900920                            <xsl:text>}</xsl:text> 
    901921                        </xsl:if> 
     
    906926        </div> 
    907927         
    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??? --> 
     928        <!-- TODO: Why do we have to do this to see Coordinate meta appear in extraMetadataList on o=xml page, when Lat and Lng appear without doing the same???  
     929            Furthermore, map-tools.xsl already requests Coordinate meta, and map-tools.xsl is always included when format statement for collection in 
     930            search|browse|doc display view has mapEnabled=true --> 
    909931        <gsf:metadata name="Coordinate" hidden="true"/> 
     932        <gsf:metadata name="GPS.mapOverlay" hidden="true"/>      
    910933    </xsl:template> 
    911934