dashboard
Version:
Create dashboards with gadgets on node.js
561 lines (482 loc) • 20.6 kB
text/xml
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>