UNPKG

dashboard

Version:

Create dashboards with gadgets on node.js

561 lines (482 loc) 20.6 kB
<?xml version="1.0" encoding="UTF-8" ?> <Module> <ModulePrefs title="Sky Viewport" height="400" scrolling="true"> <Require feature="dynamic-height"/> <Require feature="opensocial-0.8"/> <Require feature="minimessage"/> </ModulePrefs> <Content type="html"><![CDATA[ <script src="http://maps.google.com/jsapi?key=ABQIAAAAKYHb1B3NpT-mpL4s83EIgRSop_PCxtS7_vOEwBFafrYxod0JxBQK6BarsnpmKY7-BFhZ1QAd3zSaLg" type="text/javascript"></script> <script src="http://sky.astro.washington.edu/gadgets/js/gDataInterface.js" type="text/javascript"></script> <script src="http://students.washington.edu/csayres/widgetlib1.js" type="text/javascript"></script> <script src="http://sky.astro.washington.edu/gadgets/js/astroObjectLib.js" type="text/javascript"></script> <script type="text/javascript"> // run some triggers just in case it took us a while to start up and there are already some public vars we need to react to // refreshKMLFromList("VP_Point_List", _KMLPointList); // Writes to the console if debug (global) is true function debugLog(msg){ if ((debug === true) && (window.console && console.log)) { console.log(GADGET_NAME + ": " + msg); } return; } var vpe = null; // CONSTANTS var GADGET_NAME = "ViewportEarth" + "_" + Math.floor(Math.random()*100000+1).toString() debug = true; function init(){ //debugger; vpe = new ViewportEarth(); gadgets.window.adjustHeight(); } function ViewportEarth() { var my = new Object(); // CONSTANTS var DEFAULT_NAMESPACE = "NS1", MM_TIMER_DURATION = 4, TIMER_VIEWCHANGEEND = 200; // ms to wait to trigger the ge viewchangeend event // PRIVATE var namespaceList = [ DEFAULT_NAMESPACE ]; // list of our current Namespaces. Just init with the default var di = new gDataInterface(GADGET_NAME, DEFAULT_NAMESPACE); // make dataInterface object, init with default var miniMsg = new gadgets.MiniMessage();// make MiniMessage object // private Point List // first make the list item constructor function KMLListItem(){} KMLListItem.prototype = { KMLobj : null, listItemId : -1, isPlotted : false, }; var _KMLPointList = []; var msg = miniMsg.createStaticMessage("Attempting to register gadget..."); var tidsViewchangeend = []; // array of timer IDs for ge viewchangeend event // INIT Functions // init google earth (ge) var ge = null; // the google earth object is within the viewport scope google.load("earth", "1"); google.setOnLoadCallback(initGE); function initGE() { google.earth.createInstance('sky_map', initCB, failureCB); } // callback on successful creation of ge plugin instance function initCB(instance) { ge = instance; ge.getWindow().setVisibility(true); ge.getOptions().setMapType(ge.MAP_TYPE_SKY); ge.getNavigationControl().setVisibility(ge.VISIBILITY_AUTO); ge.getOptions().setStatusBarVisibility(true); // Add event listeners google.earth.addEventListener(ge.getView(), "viewchangeend", function(){ // write the new VP bounds to the public variable // TODO: This will need a timer, because the viewchangeend event fires so often when dragging slowly. // We need to make sure that we arent writing the current bounds more often than once every 250ms or so writeCurrentBounds(); }); // we can implement this stuff later if we want... //Initialize map to Sombrero Galaxy // setTimeout(function() { // var oldFlyToSpeed = ge.getOptions().getFlyToSpeed(); // ge.getOptions().setFlyToSpeed(.2); // Slow down the camera flyTo speed. // var lookAt = ge.getView().copyAsLookAt(ge.ALTITUDE_RELATIVE_TO_GROUND); // lookAt.set(-11.623055555555556, 9.997500000000002, 0,ge.ALTITUDE_RELATIVE_TO_GROUND, 262.87, 0, 6039.328125684229); // ge.getView().setAbstractView(lookAt); // ge.getOptions().setFlyToSpeed(oldFlyToSpeed); // }, 1000); // Start the zoom-in after one second. } function failureCB(errorCode) { alert("*** Error initializing google earth plugin ***"); } // REGISTRATION doRegistration(namespaceList); // REGISTRATION stuff // do complete registration for all namespaces in the array function doRegistration(namespaceArray){ // TODO: check that namespaceArray is actually and array for (var i=0, len=namespaceArray.length; i<len; i++){ registerMe(namespaceArray[i]); } } // register this gadget in a particular namespace function registerMe(namespaceName){ //F irst, Register the gadget with success and failure callbacks di.registerGadget(namespaceName, function(){continueRegistration(namespaceName);}, function(){registrationFailure(namespaceName);}); } // Callback after a successful registration of this gadget in a namespace // Displays messages and registers variables function continueRegistration(namespaceName){ debugLog('Registration was total Success!'); if (msg !== undefined) { miniMsg.dismissMessage(msg); miniMsg.createTimerMessage("Registration Succesful.", MM_TIMER_DURATION); } registerVariables(namespaceName); // di.registerVariable(); // di.addTrigger(); } // Callback after a failure of registration // displays message showing failure function registrationFailure(namespaceName){ debugLog('Registration was total failure!'); miniMsg.dismissMessage(msg); miniMsg.createDismissibleMessage("Unable to register gadget.\nWe cannot communicate with other gadgets."); } // Registers variables, and if successful, calls registerTriggers function registerVariables(namespaceName){ debugLog('Attempting to register variables...'); var varList = [ "VP_Coord", "KML_List", "img_ovly","VP_Point_List", "VP_Current_Bounds", "VP_Speed" ] // list of variables to register for (var i=0, len=varList.length; i<len; i++) { // TODO: should we do this for every namespace? if (di.registerVariable(namespaceName, varList[i], null)) { debugLog('Successfully registered variable "' + varList[i] + '"'); } else { debugLog('FAILED to register variable "' + varList[i] + '"'); } } // TODO: should we check for successful variable registration? // posisbly register one trigger at a time for each successful var? registerTriggers(namespaceName); } // registers Triggers function registerTriggers(namespaceName){ if (di.registerTrigger(namespaceName, "VP_Coord", function(){ my.moveMap(); })) { debugLog('Successfully registered trigger for "' + 'VP_Coord' + '."'); } if (di.registerTrigger(namespaceName, "KML_List", function(){ //clearKML(); showKML(); })) { debugLog('Successfully registered trigger for "' + 'KML_List' + '."'); } if (di.registerTrigger(namespaceName, "VP_Point_List", function(){ refreshKMLFromList("VP_Point_List", _KMLPointList); })) { debugLog('Successfully registered trigger for "' + 'VP_Point_List' + '."'); } if (di.registerTrigger(namespaceName, "img_ovly", function(){ //clearKML(); createGroundOverlay(); })) { debugLog('Successfully registered trigger for "' + 'img_ovly' + '."'); } if (di.registerTrigger(namespaceName, "VP_Speed", function(){ my.setFlyToSpeed(); })) { debugLog('Successfully registered trigger for "' + 'VP_Speed' + '."'); } } // METHODS // Sets the flytospeed between 0 and 5 my.setFlyToSpeed = function() { var speed = parseFloat(di.readVariable(DEFAULT_NAMESPACE, "VP_Speed")); if (!isNaN(speed)) { if ((speed >= 0) && (speed <= 5)) { ge.getOptions().setFlyToSpeed(speed); // fastest speed before ge.SPEED_TELEPORT } } } // Slews map to point (center) at new coordinate // TODO: with range? or bounding box? my.moveMap = function (){ var coord = di.readVariable(DEFAULT_NAMESPACE, "VP_Coord"); var lon = coord.getLongitude(); var lat = coord.getLatitude(); //alert("RA: " + ra + "\nDEC: " + dec); // check that ra and dec are numbers if (!isNaN(lon) && !isNaN(lat)){ var lookAt = ge.createLookAt(''); lookAt.setLatitude(lat); lookAt.setLongitude(lon); lookAt.setAltitude(0); lookAt.setHeading(0); lookAt.setRange(7000.0); ge.getView().setAbstractView(lookAt); } } writeCurrentBounds = function(){ // we need to wait a few ms so we don't trigger this event too often if (tidsViewchangeend.length !== 0){ // if the timer was already set, then clear them to reset them. clearTimerArray(tidsViewchangeend); } // now there is no timer set // so make one var tid = setTimeout(function(){ boxBounds = ge.getView().getViewportGlobeBounds(); topLeft = new UW.astro.CelestialCoordinate(0,0); topLeft.setLongitude(boxBounds.getWest()); topLeft.setLatitude(boxBounds.getNorth()); bottomRight = new UW.astro.CelestialCoordinate(0,0); bottomRight.setLongitude(boxBounds.getEast()); bottomRight.setLatitude(boxBounds.getSouth()); curBounds = [topLeft, bottomRight]; // 2-element array of CelestialCoordinates. [topLeft, bottomRight] di.writeVariable(DEFAULT_NAMESPACE, "VP_Current_Bounds", curBounds); // alert('viewchangeend: ' + curBounds[0].getRa() + ' ' + curBounds[0].getDec() + ' ' + curBounds[1].getRa() + ' ' + curBounds[1].getDec()); }, TIMER_VIEWCHANGEEND); // add the new timer id to the array tidsViewchangeend.push(tid); } function createGroundOverlay() { var img_ovly=di.readVariable(DEFAULT_NAMESPACE, "img_ovly"); var url=img_ovly[0]; var north=Number(img_ovly[1]); var south=Number(img_ovly[2]); var east=Number(img_ovly[3]); var west=Number(img_ovly[4]); var rotation=Number(img_ovly[5]); // alert(url); //alert('north '+north) //alert('south '+south) //alert('east '+east) //alert('west '+west) //alert('rotation '+rotation) var groundOverlay = ge.createGroundOverlay(''); groundOverlay.setIcon(ge.createIcon('')) groundOverlay.getIcon().setHref(url); groundOverlay.setLatLonBox(ge.createLatLonBox('')); //var center = ge.getView().copyAsLookAt(ge.ALTITUDE_RELATIVE_TO_GROUND); //var north = center.getLatitude() + .35; //alert(north) //var south = center.getLatitude() - .35; //var east = center.getLongitude() + .55; //var west = center.getLongitude() - .55; //var rotation = 0; var latLonBox = groundOverlay.getLatLonBox(); latLonBox.setBox(north, south, east, west, rotation); ge.getFeatures().appendChild(groundOverlay); // var groundOverlay = ge.createGroundOverlay(''); //groundOverlay.setIcon(ge.createIcon('')) //groundOverlay.getIcon().setHref("http://www.google.com/intl/en_ALL/images/logo.gif"); //groundOverlay.setLatLonBox(ge.createLatLonBox('')); // var center = ge.getView().copyAsLookAt(ge.ALTITUDE_RELATIVE_TO_GROUND); // alert(center.toSource()) //var latLonBox = groundOverlay.getLatLonBox(); //groundOverlay.getLatLonBox().setBox(north, south, east, west, rotation); // ge.getFeatures().appendChild(groundOverlay); } // KML function clearKML() { if (ge !== null){ var features = ge.getFeatures(); while (features.getFirstChild()) { features.removeChild(features.getFirstChild()); } } } function showKML() { var kmlList = di.readVariable(DEFAULT_NAMESPACE, "KML_List"); if (kmlList !== null) { if (kmlList.length === 0){ //clearKML(); } for (var i=0, len=kmlList.length; i<len; i++) { parsed = ge.parseKml(kmlList[i]); if (parsed !== null){ // TODO: better test for ge if (ge !== null){ ge.getFeatures().appendChild(parsed); } } else{ debugLog('Problem parsing element ' + i + ' in KML_List'); } } } } function refreshKMLFromList(pubListName, privList) { // Sync the pub and priv lists var pubList = di.readVariable(DEFAULT_NAMESPACE, pubListName); var toPlot = []; // array of ids to plot var toRemove = []; // array of ids to remove // compare the ids from pubList to the ids in the privList // first find points to remove // TODO: Is there a faster way to search these arrays? // loop thru privList looking for points NOT in pubList // loop backwards so we can splice array in loop for (var i=privList.length-1; i>=0; i--) { if (pubList.getItemById(privList[i].listItemId) === null) { // has been removed from the pubList, so add it to the toRemove list // and remove it from the privList toRemove.push(privList[i].KMLobj); // add the KMLobj to the remove list privList.splice(i,1); // remove it from privList } } // TODO: check isPlotted! // next find the new points to plot // loop thru pub list looking for points NOT in priv list (they are new points) for (var i=0, len=pubList.getLength(); i<len; i++){ var pubItemId = pubList.getIdByIndex(i); var found = false; // check for this id in the priv list for (var i2=0, len2=privList.length; i2<len2; i2++){ if (privList[i2].listItemId === pubItemId) { found = true; //break; // break actually breaks out of both for's, so lets just reset i=len // TODO: CHANGE THIS BAD FORM i2 = len; } } if (!found){ // we found a NEW point in the pubList (not in privList) // add it to the toPlot array toPlot.push(pubItemId) } } // sync the GE to the priv list // TODO: better test for GE if (ge !== null){ var geFeatures = ge.getFeatures(); // speed up the getFeatures methods // now remove the kmlobjects in toRemove for (var i=0,len=toRemove.length; i<len; i++){ geFeatures.removeChild(toRemove[i]); } // plot the kml objects in toPlot for (var i=0,len=toPlot.length; i<len; i++){ // first we plot it var kmlText = pubList.getItemByIndex(toPlot[i]).getKML(); parsed = ge.parseKml(kmlText); geFeatures.appendChild(parsed); // then add it to the privList var privItem = new KMLListItem(); privItem.KMLobj = parsed; privItem.listItemId = toPlot[i]; privItem.isPlotted = true; privList.push(privItem); } } } // HELPER function clearTimerArray(timers){ if (timers instanceof Array){ for (var i=0, len=timers.length; i<len; i++){ clearTimeout(timers.splice(i,1)); // splice returns the removed element } } } } // loopGet(); //function loopGet(){ // timeIntervalId = setInterval ( "updateCoords()", 1910); //} //function updateCoords() { //makeRequestGet("http://128.95.99.32:8891/c" + tid, 0); //tid += 1; //var coords = dataGadget.readVar("VPCoords"); //response(coords); //} //function moveMap(){ // ge.getOptions().setFlyToSpeed(ge.SPEED_TELEPORT); // var lookAt = ge.createLookAt(''); // lookAt.setLatitude(newdec); // lookAt.setLongitude(radeg); // lookAt.setAltitude(0); // lookAt.setHeading(0); // lookAt.setRange(range); // ge.getView().setAbstractView(lookAt); //} //function eventListener(){ // var lookAt = ge.getView().copyAsLookAt(ge.ALTITUDE_RELATIVE_TO_GROUND); // var globeBounds = ge.getView().getViewportGlobeBounds(); // range = lookAt.getRange(); // heading = lookAt.getHeading(); // dataWrap.range = range; // dataWrap.heading = heading; // dataWrap.earthlng = lookAt.getLongitude(); // dataWrap.earthlat = lookAt.getLatitude(); // dataWrap.north=globeBounds.getNorth(); // dataWrap.south=globeBounds.getSouth(); // dataWrap.east=(globeBounds.getEast())+180; // dataWrap.west=(globeBounds.getWest())+180; // post(); //} // // //function target(){ // var placemark = ge.createPlacemark(''); // placemark.setName(""); // var features = ge.getFeatures(); // var icon = ge.createIcon(''); // icon.setHref('http://students.washington.edu/csayres/target.png'); // var style = ge.createStyle(''); //create a new style // style.getIconStyle().setIcon(icon); //apply the icon to the style // placemark.setStyleSelector(style); //apply the style to the placemark // var point = ge.createPoint(''); // point.setLatitude(tarDEC); // point.setLongitude(tarRA-180); // placemark.setGeometry(point); // features.appendChild(placemark); //} // //function loadKml() { // google.earth.fetchKml(ge, kmlurl, function(kmlObject) { // if (kmlObject) { // ge.getFeatures().appendChild(kmlObject); // } // else { // setTimeout(function() { // alert('Bad or null KML.'); // }, 0); // // } // }) //} // // //function response(obj) { // // if (obj.text.search(/^cellng.*$/gm) != -1){ // newRA = ((obj.text.match(/^cellng.*$/gm)).toString()).slice(7)-0; // } // if (obj.text.search(/^cellat.*$/gm) != -1){ // newDec = ((obj.text.match(/^cellat.*$/gm)).toString()).slice(7)-0; // } // if (obj.text.search(/^tarRA.*$/gm) != -1){ // tarRAtest = ((obj.text.match(/^tarRA.*$/gm)).toString()).slice(6)-0; // } // if (obj.text.search(/^tarDEC.*$/gm) != -1){ // tarDECtest = ((obj.text.match(/^tarDEC.*$/gm)).toString()).slice(7)-0; // } // if (obj.text.search(/^kmlurl.*$/gm) != -1){ // kmlurlnew=((obj.text.match(/^kmlurl.*$/gm)).toString()).slice(7).toString(); // kmlurlnew=kmlurlnew.replace(/%3A/g, ":"); // kmlurlnew=kmlurlnew.replace(/%2F/g, "/"); // kmlurlnew=kmlurlnew.replace(/%3D/g, "="); // kmlurlnew=kmlurlnew.replace(/%26/g, "&"); // kmlurlnew=kmlurlnew.replace(/%3F/g, "?"); // } // else{ // setTimeout("doNothing()", 10); // } // // if (newRA != radeg || newDec != newdec) { // radeg = newRA; newdec = newDec; // moveMap(); // } // if (tarRAtest != tarRA || tarDECtest != tarDEC){ // tarRA=tarRAtest;tarDEC=tarDECtest; // target(); // } // if (kmlurlnew != kmlurl){ // kmlurl=kmlurlnew; // loadKml(); // } //} function doNothing(){} gadgets.util.registerOnLoadHandler(init); </script> <div id="sky_map" style="height:400px; width:100%;"> <!-- <input type="button" value="clear KML" onclick="ks.clearKML()"> --> </div> ]]></Content> </Module>