IONIC.defns ("api.imagearchive"); /** * @constructor * * @class * A {@link IONIC.api.imagearchive.ServerRef} points to an image * archive server. * *
* An image archive server can be in application scope, reachable * through an URL, ... *
** This is an abstract type. *
*/ IONIC.api.imagearchive.ServerRef = function () { }; /** * Get a server-friendly representation of the image archive server * reference, ready to be JSON-serialized. * ** This dummy implementation will throw an exception *
* * @return {object} an object, ready to be JSON-serialized to the * server. */ IONIC.api.imagearchive.ServerRef.prototype.toTransportFormat = function () { IONIC.misc.unimp ("IONIC.api.imagearchive.ServerRef", "toTransportFormat"); }; /** * @constructor * * @class * An {@link IONIC.api.imagearchive.ApplicationScopeServerRef} points * to an image archive server that's available in the application * scope. * * @extends IONIC.api.imagearchive.ServerRef * */ IONIC.api.imagearchive.ApplicationScopeServerRef = function (id) { this._id = id; }; IONIC.misc.extendType (IONIC.api.imagearchive.ApplicationScopeServerRef, IONIC.api.imagearchive.ServerRef); /** * Get the ID in application scope under which this image archive * server is available. * * @return {string} the ID in application scope */ IONIC.api.imagearchive.ApplicationScopeServerRef.prototype.getId = function () { return this._id; }; /** * Get a server-friendly representation of the image archive server * reference * * @return {object} an object, ready to be JSON-serialized to the * server. */ IONIC.api.imagearchive.ApplicationScopeServerRef.prototype.toTransportFormat = function () { var tf = {}; tf.type = "applicationScope"; tf.id = this.getId (); return tf; }; /** * @constructor * * @class * An {@link IONIC.api.imagearchive.SessionScopeServerRef} points * to an image archive server that's available in the session * scope. * * @extends IONIC.api.imagearchive.ServerRef * */ IONIC.api.imagearchive.SessionScopeServerRef = function (id) { this._id = id; }; IONIC.misc.extendType (IONIC.api.imagearchive.SessionScopeServerRef, IONIC.api.imagearchive.ServerRef); /** * Get the ID in session scope under which this image archive * server is available. * * @return {string} the ID in session scope */ IONIC.api.imagearchive.SessionScopeServerRef.prototype.getId = function () { return this._id; }; /** * Get a server-friendly representation of the image archive server * reference * * @return {object} an object, ready to be JSON-serialized to the * server. */ IONIC.api.imagearchive.SessionScopeServerRef.prototype.toTransportFormat = function () { var tf = {}; tf.type = "sessionScope"; tf.id = this.getId (); return tf; }; /* * Copyright 2005- by IONIC Software S.A., * 18 Av Wallonie, 4460 Grace-Hollogne, Belgium. * All rights reserved. * * This software is the confidential and proprietary information * of IONIC Software S.A.("Confidential Information"). * You shall not disclose such Confidential Information and shall use * it only in accordance with the terms of the license agreement * you entered into with IONIC Software. * * * IMPORTANT * * This file is internal to RedSpider Enterprise Tilapia toolkit * add-ons. It is subject to changes and CANNOT BE DIRECTLY ACCESSED * BY APPLICATIONS. Only the objects contained in the IONIC.api * package may be used. */ IONIC.defns ("imagearchive"); /** * @constructor * * @class * The {@link IONIC.imagearchive.ImageArchiveTool} is the low-level * JavaScript interface to an ImageArchive server. * * @extends IONIC.misc.RequestTool * ** This shouldn't be used directly by applications, but is used by * higher-level tools. *
* * @param {IONIC.api.imagearchive.ServerRef} serverRef A reference to * the ImageArchive server */ IONIC.imagearchive.ImageArchiveTool = function (serverRef) { IONIC.misc.RequestTool.call (this); this._sr = serverRef; this.onQueryStart = new YAHOO.util.CustomEvent ("onQueryStart"); this.onQuery = new YAHOO.util.CustomEvent ("onQuery"); }; IONIC.misc.extendType (IONIC.imagearchive.ImageArchiveTool, IONIC.misc.RequestTool); /** * Get the ImageArchive server reference. * * @return {IONIC.api.imagearchive.ServerRef} the server reference */ IONIC.imagearchive.ImageArchiveTool.prototype.getServerRef = function () { return this._sr; }; /** * @private */ IONIC.imagearchive.ImageArchiveTool.prototype.getUrlForAction = function (action) { return IONIC.misc.getWebappBaseUrl () + "/" + action + ".do?serverRef=" + escape (JSON.stringify (this.getServerRef ().toTransportFormat ())); }; /** * @private */ IONIC.imagearchive.ImageArchiveTool.prototype.getGetStatusUrl = function () { return this.getUrlForAction ("iaGetStatus"); }; /** * @private */ IONIC.imagearchive.ImageArchiveTool.prototype.getSearchUrl = function (epsgId) { return this.getUrlForAction ("iaSearch") + "&epsgId=" + escape (epsgId); }; /** * @private */ IONIC.imagearchive.ImageArchiveTool.prototype.getWfsSearchUrl = function (epsgId) { return this.getUrlForAction ("iaWfsSearch") + "&epsgId=" + escape (epsgId); }; /** * An URL that returns the ISO 19115 metadata corresponding to a feature type described * by its object id. * @param {string} id The object id. */ IONIC.imagearchive.ImageArchiveTool.prototype.getWfsISO19115SearchUrl = function (id) { return this.getUrlForAction ("iaWfsSearch") + "&action=iso19115&id=" + escape (id); }; /** * @private */ IONIC.imagearchive.ImageArchiveTool.prototype.getGetObjectByNameUrl = function (name, epsgId, full) { return this.getUrlForAction ("iaGetByName") + "&objectName=" + escape (name) + "&epsgId=" + escape (epsgId) + "&fullDescription=" + escape (full); }; /** * @private */ IONIC.imagearchive.ImageArchiveTool.prototype.getGetObjectByIdUrl = function (id, epsgId, full) { return this.getUrlForAction ("iaGetByName") + "&objectId=" + escape (id) + "&epsgId=" + escape (epsgId) + "&fullDescription=" + escape (full); }; /** * @private */ IONIC.imagearchive.ImageArchiveTool.prototype.getGetCoverageByNameUrl = function (name, epsgId, full) { return this.getUrlForAction ("iaCoverageByName") + "&objectName=" + escape (name) + "&epsgId=" + escape (epsgId) + "&fullDescription=" + escape (full); }; /** * The default width of a thumbnail */ IONIC.imagearchive.ImageArchiveTool.DEFAULT_THUMBNAIL_WIDTH = +("100" || 100); /** * The default height of a thumbnail */ IONIC.imagearchive.ImageArchiveTool.DEFAULT_THUMBNAIL_HEIGHT = +("100" || 100); /** * Build the URL for fetching, as an image, the thumbnail * corresponding to the object with the given name. * * @param {string} objectName The name of the object * @param {int} width (optional) The width, in pixels, of the * thumbnail. Defaults to * {@link IONIC.imagearchive.ImageArchiveTool.DEFAULT_THUMBNAIL_WIDTH}. * @param {int} height (optional) The height, in pixels, of the * thumbnail. Defaults to * {@link IONIC.imagearchive.ImageArchiveTool.DEFAULT_THUMBNAIL_HEIGHT}. */ IONIC.imagearchive.ImageArchiveTool.prototype.getThumbnailUrl = function (objectName, width, height) { var base = this.getUrlForAction ("iaThumbnail"); return base + "&objectName=" + escape(objectName) + "&width=" + (width || IONIC.imagearchive.ImageArchiveTool.DEFAULT_THUMBNAIL_WIDTH) + "&height=" + (height || IONIC.imagearchive.ImageArchiveTool.DEFAULT_THUMBNAIL_HEIGHT); }; /** * @constructor * * @class * This defines a custom queryable for the search panel. * ** A custom queryable is a search criteria that the server * advertises as being available, and is one of the types: *
name, operator and
* value, for searching on custom parameters.
*
* @param {int} epsgId The EPSG ID in which the spatial extent must be
* expressed
*
* @param {function} beginCallback The begin callback
*
* @param {function} iterationCallback The iteration callback
*
* @param {function} endCallback The end callback
*/
IONIC.imagearchive.ImageArchiveTool.prototype.executeSearch = function (keywords,
resultsType,
resultsAvailability,
resultsCount,
spatialBounds,
temporalBounds,
minimumQuality,
minimumResolution,
customQueryables,
epsgId,
beginCallback,
iterationCallback,
endCallback) {
var self = this;
var query = {
keywords : keywords,
resultsType : resultsType,
resultsAvailability : resultsAvailability,
resultsCount : resultsCount,
spatialBounds : spatialBounds ? IONIC.geom.JGTFTool.geometryToJGTF (spatialBounds) : undefined,
temporalBounds : temporalBounds ? (
IONIC.misc.mapcar1 (
function (date) {
if (date) {
return date.toISO8601String ();
} else {
return null;
}
}, temporalBounds)) : undefined,
minimumQuality : minimumQuality,
minimumResolution : minimumResolution,
customQueryables : customQueryables
};
var serverRef = this.getServerRef ();
var queryId = gensym ();
var time = new Date ().getTime ();
this.onQueryStart.fire ("search", query, queryId);
this.withUrl (this.getSearchUrl (epsgId),
"POST",
this._wrapIterationCallbacks (
beginCallback,
iterationCallback,
function (success, parsedObject, thisReq) {
self.onQuery.fire ("search", query, parsedObject, (new Date ().getTime () - time) / 1000, queryId);
if (endCallback) {
endCallback.apply (self, arguments);
}
},
null,
null,
function (data) {
return IONIC.api.imagearchive.IAObject.fromTransportFormat(
serverRef,
data);
},
"records"),
JSON.stringify (query));
};
/**
* Execute a search for WFS objects on the ImageArchive server, according to the
* parameters that are passed as arguments.
*
* @param {string} keywords A string of keywords (separated by white
* spaces)
*
* @param {int} resultsCount The max number of results (-1 means: no
* limit)
*
* @param {object} spatialBounds A geometry, from the package
* IONIC.api.geom.*, or null/undefined if no spatial boundary
*
* @param {string[]} temporalBounds An array of two ISO8601-formatted
* dates. If the array is null/undefined, there is no temporal
* boundary. Also, if either of the two (or the two) boundaries are
* null/undefined, those will be ignored
*
* @param {int} epsgId The EPSG ID in which the spatial extent must be
* expressed
*
* @param {function} beginCallback The begin callback
*
* @param {function} iterationCallback The iteration callback
*
* @param {function} endCallback The end callback
*/
IONIC.imagearchive.ImageArchiveTool.prototype.executeWfsSearch = function (keywords,
resultsCount,
spatialBounds,
temporalBounds,
epsgId,
beginCallback,
iterationCallback,
endCallback) {
var self = this;
var query = {
keywords : keywords,
resultsCount : resultsCount,
spatialBounds : spatialBounds ? IONIC.geom.JGTFTool.geometryToJGTF (spatialBounds) : undefined,
temporalBounds : temporalBounds ? (
IONIC.misc.mapcar1 (
function (date) {
if (date) {
return date.toISO8601String ();
} else {
return null;
}
}, temporalBounds)) : undefined
};
var serverRef = this.getServerRef ();
var time = new Date ().getTime ();
var queryId = gensym ();
this.onQueryStart.fire ("wfsSearch", query, queryId);
this.withUrl (this.getWfsSearchUrl (epsgId),
"POST",
this._wrapIterationCallbacks (
beginCallback,
iterationCallback,
function (success, parsedObject, thisReq) {
self.onQuery.fire ("wfsSearch", query, parsedObject, (new Date ().getTime () - time) / 1000, queryId);
if (endCallback) {
endCallback.apply (self, arguments);
}
},
null,
null,
function (wfsObject) {
if (wfsObject.footprint) {
wfsObject.footprint = IONIC.geom.JGTFTool.JGTFToGeometry (wfsObject.footprint);
}
return wfsObject;
},
"wfsRecords"),
JSON.stringify (query));
};
/**
* Fetch the object corresponding to the given name.
*
*
* By default, only the primary information about that object is
* retrieved. If you want to retrieve (parts of) information about
* the children of this object, as well as the axes/bands this
* coverage object might propose, you'll need to pass
* true as last parameter.
*
true if you want
* to retrieve information about the children and the axes/bands.
*
* @see #withCoverageByName
*/
IONIC.imagearchive.ImageArchiveTool.prototype.withObjectByName = function (name, epsgId, callback, full) {
// the name is actually a uuid; call proper method
if (name.indexOf("urn:")>=0) return this.withObjectById(name, epsgId, callback, full);
if (typeof epsgId !== "number")
throw "Missing EPSG ID";
var self = this;
var time = new Date ().getTime ();
var queryId = gensym ();
this.onQueryStart.fire ("objectByName", name, queryId);
this.withUrl (this.getGetObjectByNameUrl (name, epsgId, !! full),
"GET",
function (success, data) {
self.onQuery.fire ("objectByName", name, data, (new Date ().getTime () - time) / 1000, queryId);
if (callback) {
var obj = IONIC.api.imagearchive.IAObject.fromTransportFormat(
self.getServerRef (), data);
obj.isFull = full;
callback(obj);
}
});
};
/**
* Fetch the object corresponding to the given uuid.
*
*
* By default, only the primary information about that object is
* retrieved. If you want to retrieve (parts of) information about
* the children of this object, as well as the axes/bands this
* coverage object might propose, you'll need to pass
* true as last parameter.
*
true if you want
* to retrieve information about the children and the axes/bands.
*
* @see #withCoverageByName
*/
IONIC.imagearchive.ImageArchiveTool.prototype.withObjectById = function (id, epsgId, callback, full) {
if (typeof epsgId !== "number")
throw "Missing EPSG ID";
var self = this;
var time = new Date ().getTime ();
var queryId = gensym ();
this.onQueryStart.fire ("objectByName", id, queryId);
this.withUrl (this.getGetObjectByIdUrl (id, epsgId, !! full),
"GET",
function (success, data) {
self.onQuery.fire ("objectByName", id, data, (new Date ().getTime () - time) / 1000, queryId);
if (callback) {
var obj = IONIC.api.imagearchive.IAObject.fromTransportFormat(
self.getServerRef (), data);
obj.isFull = full;
callback(obj);
}
});
};
/**
* Fetch the object corresponding to the given name,
* as a coverage (which means this will include more information, such
* as: the axes, request/response CRSes, formats, ...).
*
*
* By default, only the primary information about that object is
* retrieved. If you want to retrieve (parts of) information about
* the children of this object, as well as the axes/bands this
* coverage object might propose, you'll need to pass
* true as last parameter.
*
true if you want
* to retrieve information about the children and the axes/bands.
*
* @see #withObjectByName
*/
IONIC.imagearchive.ImageArchiveTool.prototype.withCoverageByName = function (name, epsgId, callback, full) {
// FIXME: lots of copy/paste code w/ prev fun. --ad 070903
if (typeof epsgId !== "number")
throw "Missing Epsg Id";
var self = this;
var time = new Date ().getTime ();
var queryId = gensym ();
this.onQueryStart.fire ("coverageByName", name, queryId);
this.withUrl (this.getGetCoverageByNameUrl (name, epsgId, !! full),
"GET",
function (success, data) {
self.onQuery.fire ("objectByName", name, data, (new Date ().getTime () - time) / 1000, queryId);
if (callback) {
callback (IONIC.api.imagearchive.IAObject.fromTransportFormat(
self.getServerRef (), data));
}
});
};
/*
* Copyright 2005- by IONIC Software S.A.,
* 18 Av Wallonie, 4460 Grace-Hollogne, Belgium.
* All rights reserved.
*
* This software is the confidential and proprietary information
* of IONIC Software S.A.("Confidential Information").
* You shall not disclose such Confidential Information and shall use
* it only in accordance with the terms of the license agreement
* you entered into with IONIC Software.
*
*
* IMPORTANT
*
* This file is internal to RedSpider Enterprise Tilapia toolkit
* add-ons. It is subject to changes and CANNOT BE DIRECTLY ACCESSED
* BY APPLICATIONS. Only the objects contained in the IONIC.api
* package may be used.
*/
/**
* Build an abstract panel
* @constructor
*
* @extends IONIC.imagearchive.AbstractImageArchivePanel
*
* @class
*
* A {@link IONIC.imagearchive.AbstractImageArchivePanel} is the base
* for all ImageArchive panels
*
* @param {HTMLElement} htmlElt The containing HTML element, or it's
* ID.
*
* @param {IONIC.api.imagearchive.ServerRef} serverRef A reference to
* the image archive server
*
* @param {HTMLWindow} win (Optional) The window in which is the
* document holding the element named "htmlElt", if "htmlElt" is
* a string (defaults to the current window).
*/
IONIC.imagearchive.AbstractImageArchivePanel = function (htmlElt, serverRef, win) {
win = win || window;
var dh = new IONIC.api.ui.DomHelper (win.document);
this._dh = dh;
this._iastool = new IONIC.imagearchive.ImageArchiveTool (serverRef);
this._editors = {};
this._htmlElt = dh.get(htmlElt);
};
/**
* Get the associated {@link IONIC.imagearchive.ImageArchiveTool}
*
* @return {IONIC.imagearchive.ImageArchiveTool}
*/
IONIC.imagearchive.AbstractImageArchivePanel.prototype.getImageArchiveTool = function () {
return this._iastool;
};
/**
* Get the {@link IONIC.api.ui.DomHelper} associated to this panel.
*
* @return {IONIC.api.ui.DomHelper} the helper
*/
IONIC.imagearchive.AbstractImageArchivePanel.prototype.getDomHelper = function () {
return this._dh;
};
/**
* Get the HTMLElement associated with this panel.
*
* @return {HTMLElement} the element
*/
IONIC.imagearchive.AbstractImageArchivePanel.prototype.getElement = function () {
return this._htmlElt;
};
/**
* Get the {@link IONIC.api.imagearchive.ServerRef} associated to this
* panel.
*
* @return {IONIC.api.imagearchive.ServerRef} the server reference
*/
IONIC.imagearchive.AbstractImageArchivePanel.prototype.getServerRef = function () {
return this.getImageArchiveTool ().getServerRef ();
};
/**
* Get the {@link IONIC.api.maps.Map} that is associated to this
* instance.
*
* @return {IONIC.api.maps.Map} the associated map
*/
IONIC.imagearchive.AbstractImageArchivePanel.prototype.getAssociatedMap = function () {
return this._map;
};
/**
* Set the {@link IONIC.api.maps.Map} that is associated to this
* instance.
*
* * Attaching a {@link IONIC.api.maps.Map} to an instance of this * type will force the ImageArchive objects' spatial extents to be * expressed in that map's EPSG ID. *
* * @param {IONIC.api.maps.Map} map The map to be associated to this * instance. */ IONIC.imagearchive.AbstractImageArchivePanel.prototype.setAssociatedMap = function (map) { this._map = map; }; /** * Returns the preferred epsg ID for any query this panel might have * to make. * ** If there is a {@link IONIC.api.maps.Map} associated to this * panel, it's epsgId will be used. Otherwise, -1 is returned. *
* * @return {int} the epsg ID */ IONIC.imagearchive.AbstractImageArchivePanel.prototype.getPreferredEpsgId = function () { var map = this.getAssociatedMap (); return ((map && map.getBox ()) ? map.getBox ().epsgId : -1); }; /** * Builds an {@link IONIC.ui.AbstractSpatialEditor} that will be used * for retrieving the box for a query. * ** This implementation will simply build an editable <input> * field-based editor that, when asked for it's value * (see {@link IONIC.ui.AbstractEditor#getValue}) will try and * read a comma-separated representation of a box in what's been * typed in and return a geometry (a {@link IONIC.api.geom.Polygon}) * if it succeeds. *
** It's up to the implementation/specialization of this * {@link IONIC.imagearchive.AbstractImageArchivePanel} to fill the * editor with the comma-separated representation of a box. (for * example, by listening to the "onSelectedBoxChanged" event of a * {@link IONIC.api.maps.Map}). *
*
* Note: When the getValue function is called on
* an editor that is created by this function, the returned type
* will be a {@link IONIC.api.geom.Polygon} of 1 ring, with 4
* points, representing the box, and not a
* {@link IONIC.api.geom.Box} instance.
*
* In order to get the {@link #getOperator} to work properly, the * component for this editor must embed an HTML <select> * element, allowing the user to select the operator. *
* * @extend IONIC.ui.InputEditor * * @param {HTMLElement} component An HTML component */ IONIC.imagearchive.editors.CustomQueryableInputEditor = function (component) { IONIC.ui.InputEditor.call (this, component); }; IONIC.misc.extendType (IONIC.imagearchive.editors.CustomQueryableInputEditor, IONIC.ui.InputEditor); /** * Make a new instance * * @param {IONIC.api.ui.DomHelper} dh A dom helper to build the * element * @return {IONIC.ui.InputEditor} */ IONIC.imagearchive.editors.CustomQueryableInputEditor.newInstance = function (dh) { var div = IONIC.imagearchive.editors.CustomQueryableInputEditor.buildComponent (dh); return new IONIC.imagearchive.editors.CustomQueryableInputEditor (div); }; /** * Builds a component useful for the {@link IONIC.imagearchive.editors.CustomQueryableInputEditor} * editor. * * @param {IONIC.api.ui.DomHelper} dh A DOM helper used to build the component. * @param {boolean} includeLikeOperator Include the 'like' operator in the choice list. * @return {HTMLElement} The element built. */ IONIC.imagearchive.editors.CustomQueryableInputEditor.buildComponent = function (dh, includeLikeOperator) { if (typeof includeLikeOperator === "undefined") { includeLikeOperator = true; } var inp = dh.elt ("input"); inp.type = "text"; inp.disabled = true; var stor = dh.elt ("select"); dh.mkOpt (stor, "- Select -").value = "- Select -"; dh.mkOpt (stor, "=").value = IONIC.imagearchive.ImageArchiveTool.Queryable.OP_EQL; dh.mkOpt (stor, ">=").value = IONIC.imagearchive.ImageArchiveTool.Queryable.OP_GREATER_OR_EQL; dh.mkOpt (stor, ">").value = IONIC.imagearchive.ImageArchiveTool.Queryable.OP_GREATER; dh.mkOpt (stor, "<=").value = IONIC.imagearchive.ImageArchiveTool.Queryable.OP_LESS_OR_EQL; dh.mkOpt (stor, "<").value = IONIC.imagearchive.ImageArchiveTool.Queryable.OP_LESS; if (includeLikeOperator) { dh.mkOpt (stor, "like").value = IONIC.imagearchive.ImageArchiveTool.Queryable.OP_LIKE; } // Disable values selector if operator is not selected stor.onchange = function () { inp.disabled = (stor.options.selectedIndex == 0) ? true : false; }; return dh.elt ("div", stor, inp); }; /** * Returns the operator that was selected (null if none). * * @return the operator */ IONIC.imagearchive.editors.CustomQueryableInputEditor.prototype.getOperator = function () { var stor = this.getComponent ().getElementsByTagName ("select") [0]; if (stor.options.selectedIndex == 0) { return null; } return stor.options [stor.options.selectedIndex].value; }; /** * Returns the value that was entered (null if none). * * @return the value */ IONIC.imagearchive.editors.CustomQueryableInputEditor.prototype.getValue = function () { if (!this.getOperator ()) { return null; } return this.refineValue (this.getComponent ().getElementsByTagName ("input") [0].value); }; /* * Copyright 2005- by IONIC Software S.A., * 18 Av Wallonie, 4460 Grace-Hollogne, Belgium. * All rights reserved. * * This software is the confidential and proprietary information * of IONIC Software S.A.("Confidential Information"). * You shall not disclose such Confidential Information and shall use * it only in accordance with the terms of the license agreement * you entered into with IONIC Software. */ /** * @constructor * * @class * A date editor. * * @extend IONIC.ui.InputEditor * ** Since building an HTML component for this type of editor is * rather complex, and follows strict rules, you might want to have * a look at * {@link IONIC.imagearchive.editors.CustomQueryableDateEditor#buildComponent}. *
* * @param {HTMLElement} component An HTML component for this editor * * @see IONIC.imagearchive.editors.CustomQueryableDateEditor#buildComponent */ IONIC.imagearchive.editors.CustomQueryableDateEditor = function (component) { IONIC.ui.InputEditor.call (this, component); }; IONIC.misc.extendType (IONIC.imagearchive.editors.CustomQueryableDateEditor, IONIC.ui.InputEditor); IONIC.imagearchive.editors.CustomQueryableDateEditor.newInstance = function (dh) { var component = IONIC.imagearchive.editors.CustomQueryableDateEditor.buildComponent (dh); return new IONIC.imagearchive.editors.CustomQueryableDateEditor (component); } /** * Retrieve the value for this editor. * * @return {Date} the selected date. */ IONIC.imagearchive.editors.CustomQueryableDateEditor.prototype.getValue = function () { return this.getComponent ().getValue (); }; /** * Retrieve the operator for this editor. * * @return {string} the operator. */ IONIC.imagearchive.editors.CustomQueryableDateEditor.prototype.getOperator = function () { return this.getComponent ().getOperator (); }; /** * Build an HTML component, typically targetted at the * {@link IONIC.imagearchive.editors.CustomQueryableDateEditor} * type. * ** The component will have two properties, namely * "getOperator" and "getValue" from where an * {@link IONIC.imagearchive.editors.CustomQueryableDateEditor} * instance will be able to retrieve the information it needs. *
* * @param {IONIC.api.ui.DomHelper} dh A DomHelper to build the * component * @return {HTMLElement} an HTML component */ IONIC.imagearchive.editors.CustomQueryableDateEditor.buildComponent = function (dh) { var inputComponent = IONIC.imagearchive.editors.CustomQueryableInputEditor.buildComponent (dh, false); var inputEditor = new IONIC.imagearchive.editors.CustomQueryableInputEditor (inputComponent); var dateComponent = inputComponent.getElementsByTagName("input")[0]; var operatorComponent = inputComponent.getElementsByTagName("select")[0]; var startCalendarHolder = dh.elt ("div.timestampCalendar"); startCalendarHolder.id = gensym ("cphdr"); startCalendarHolder.style.position = "absolute"; startCalendarHolder.style.visibility = "hidden"; startCalendarHolder.style.backgroundColor = "white"; dh.append (dh.getDocument ().body, startCalendarHolder); var startCalendarHook = dh.elt ("img"); startCalendarHook.id = gensym ("chk"); startCalendarHook.src = IONIC.misc.getWebappBaseUrl () + "/images/editor/timestamp/calendar.gif"; startCalendarHook.alt = "calendar"; startCalendarHook.title = "Open calendar"; var startClear = dh.elt ("img"); startClear.src = IONIC.misc.getWebappBaseUrl () + "/images/editor/timestamp/clear.gif"; startClear.alt = "tilapia.editor.timestamp.clear.alt"; startClear.title = "tilapia.editor.timestamp.clear.title"; var startCal = new CalendarPopup (startCalendarHolder.id); var win = window; // DH should provide this! var startCBName = gensym ("startCalCb"); win [startCBName] = function (y, m, d) { var date = new Date (y, m, d); dateComponent.value = date.toLocaleDateString (); dateComponent.dateValue = date; }; startCal.setReturnFunction (startCBName); startCalendarHook.onclick = function () { startCal.showCalendar (startCalendarHook.id); return false; }; startClear.onclick = function () { dateComponent.value = ""; dateComponent.dateValue = undefined; }; var cpnt = dh.elt ("div", inputComponent, startCalendarHook, startClear); cpnt.getValue = function () { return dateComponent.dateValue; }; cpnt.getOperator = function () { return inputEditor.getOperator (); }; return cpnt; }; /* * Copyright 2005- by IONIC Software S.A., * 18 Av Wallonie, 4460 Grace-Hollogne, Belgium. * All rights reserved. * * This software is the confidential and proprietary information * of IONIC Software S.A.("Confidential Information"). * You shall not disclose such Confidential Information and shall use * it only in accordance with the terms of the license agreement * you entered into with IONIC Software. */ /** * @constructor * * @class * A date editor. * * @extend IONIC.ui.InputEditor * ** Since building an HTML component for this type of editor is * rather complex, and follows strict rules, you might want to have * a look at * {@link IONIC.imagearchive.editors.CustomQueryableIntEditor#buildComponent}. *
* * @param {HTMLElement} component An HTML component for this editor * * @see IONIC.imagearchive.editors.CustomQueryableIntEditor#buildComponent */ IONIC.imagearchive.editors.CustomQueryableIntEditor = function (component) { IONIC.ui.InputEditor.call (this, component); }; IONIC.misc.extendType (IONIC.imagearchive.editors.CustomQueryableIntEditor, IONIC.imagearchive.editors.CustomQueryableInputEditor); IONIC.imagearchive.editors.CustomQueryableIntEditor.newInstance = function (dh) { var component = IONIC.imagearchive.editors.CustomQueryableIntEditor.buildComponent (dh); return new IONIC.imagearchive.editors.CustomQueryableIntEditor (component); } /** * Retrieve the value for this editor. * * @return {int} the selected date. */ IONIC.imagearchive.editors.CustomQueryableIntEditor.prototype.getValue = function () { return this.getComponent ().getValue (); }; /** * Retrieve the operator for this editor. * * @return {string} the operator. */ IONIC.imagearchive.editors.CustomQueryableIntEditor.prototype.getOperator = function () { return this.getComponent ().getOperator (); }; /** * Build an HTML component, typically targetted at the * {@link IONIC.imagearchive.editors.CustomQueryableIntEditor} * type. * ** The component will have two properties, namely * "getOperator" and "getValue" from where an * {@link IONIC.imagearchive.editors.CustomQueryableIntEditor} * instance will be able to retrieve the information it needs. *
* * @param {IONIC.api.ui.DomHelper} dh A DomHelper to build the * component * @return {HTMLElement} an HTML component */ IONIC.imagearchive.editors.CustomQueryableIntEditor.buildComponent = function (dh) { var inputComponent = IONIC.imagearchive.editors.CustomQueryableInputEditor.buildComponent (dh, false); var inputEditor = new IONIC.imagearchive.editors.CustomQueryableInputEditor (inputComponent); inputComponent.getValue = function () { return parseInt (inputEditor.getValue ()); }; inputComponent.getOperator = function () { return inputEditor.getOperator (); }; return inputComponent; }; /* * Copyright 2005- by IONIC Software S.A., * 18 Av Wallonie, 4460 Grace-Hollogne, Belgium. * All rights reserved. * * This software is the confidential and proprietary information * of IONIC Software S.A.("Confidential Information"). * You shall not disclose such Confidential Information and shall use * it only in accordance with the terms of the license agreement * you entered into with IONIC Software. * * * IMPORTANT * * This file is internal to RedSpider Enterprise Tilapia toolkit * add-ons. It is subject to changes and CANNOT BE DIRECTLY ACCESSED * BY APPLICATIONS. Only the objects contained in the IONIC.api * package may be used. */ IONIC.defns ("imagearchive.editors"); /** * @constructor * * @class * An editor, based on an <select> element, that implements the * {@link #getOperator} function * * @extend IONIC.ui.SelectEditor * * @param {HTMLSelect} component An HTML <select> element. */ IONIC.imagearchive.editors.CustomQueryableSelectEditor = function (component) { IONIC.ui.InputEditor.call (this, component); }; IONIC.misc.extendType (IONIC.imagearchive.editors.CustomQueryableSelectEditor, IONIC.ui.InputEditor); IONIC.imagearchive.editors.CustomQueryableSelectEditor.newInstance = function (dh) { var opSelect = new IONIC.ui.SelectEditor (dh.elt ("select")); opSelect.setOptions ([ "=" ], dh); valuesSelect = new IONIC.ui.SelectEditor (dh.elt ("select")); valuesSelect.getComponent ().disabled = true; // initially disabled var div = dh.elt ("div", opSelect.getComponent (), valuesSelect.getComponent ()); // Disable values selector if operator is not selected opSelect.getComponent ().onchange = function () { valuesSelect.getComponent ().disabled = (opSelect.getValue ()) ? false : true; }; var instance = new IONIC.imagearchive.editors.CustomQueryableSelectEditor (div); instance.opSelect = opSelect; instance.valuesSelect = valuesSelect; return instance; }; IONIC.imagearchive.editors.CustomQueryableSelectEditor.prototype.setOptions = function (ev, dh, noprompt) { this.valuesSelect.setOptions (ev, dh, noprompt); }; /** * Returns * {@link IONIC.imagearchive.ImageArchiveTool.Queryable.OP_EQL}. * * @return {IONIC.imagearchive.ImageArchiveTool.Queryable.OP_EQL} */ IONIC.imagearchive.editors.CustomQueryableSelectEditor.prototype.getOperator = function () { return IONIC.imagearchive.ImageArchiveTool.Queryable.OP_EQL; }; /** * Returns the value of this select box, or undefined if unknown. * * @return {string} the value. */ IONIC.imagearchive.editors.CustomQueryableSelectEditor.prototype.getValue = function () { if (this.opSelect.getValue ()) { return this.valuesSelect.getValue (); } else { return undefined; } }; /* * Copyright 2005- by IONIC Software S.A., * 18 Av Wallonie, 4460 Grace-Hollogne, Belgium. * All rights reserved. * * This software is the confidential and proprietary information * of IONIC Software S.A.("Confidential Information"). * You shall not disclose such Confidential Information and shall use * it only in accordance with the terms of the license agreement * you entered into with IONIC Software. * * * IMPORTANT * * This file is internal to RedSpider Enterprise Tilapia toolkit * add-ons. It is subject to changes and CANNOT BE DIRECTLY ACCESSED * BY APPLICATIONS. Only the objects contained in the IONIC.api * package may be used. */ IONIC.defns ("imagearchive.editors"); /** * Build a channel-selector editor * * @constructor * * @extends IONIC.ui.AbstractMultiValuedEditor * * @class * An editor, based on an <select> element, with multiple * choices allowed, that allow the user to select what channels/bands * to retrieve in aGetCoverage request.
*
* * This type of editor requires a very specific type of * component. Unless you absolutely know what you're doing, * you're strongly advised to have a look at * {@link IONIC.imagearchive.editors.GetCoverageChannelEditor#buildComponent} * for building such a component. *
* * @param {HTMLElement} component An HTML component */ IONIC.imagearchive.editors.GetCoverageChannelEditor = function (component) { IONIC.ui.InputEditor.call (this, component); }; IONIC.misc.extendType (IONIC.imagearchive.editors.GetCoverageChannelEditor, IONIC.ui.AbstractMultiValuedEditor); /** * Static factory for components that match the * {@link IONIC.imagearchive.editors.GetCoverageChannelEditor} * requirements. * * @param {IONIC.api.ui.DomHelper} dh A dom helper for building the * component. * * @param {IONIC.api.imagearchive.IAObject} iaObj An object that's * used to extract the channel info from. * * @return {HTMLElement} a component */ IONIC.imagearchive.editors.GetCoverageChannelEditor.buildComponent = function (dh, iaObj) { // --------- // Left list var left = dh.elt ("select"); left.multiple = true; left.ondblclick = function () { transfer.transferRight (); }; IONIC.misc.forEach (function (channel) { dh.mkOpt (left, channel); }, iaObj.getAxisSet ().getChannelAxe ().getValues ()); // ---------- // Right list var right = dh.elt ("select"); right.multiple = true; right.ondblclick = function () { transfer.transferLeft (); }; // ------ // Center var mkTo = function (what, functionName) { var img = dh.elt ("img"); img.src = IONIC.misc.getWebappBaseUrl () + "/images/imagearchive/getcoverage/" + what + ".gif"; img.onclick = function () { transfer [functionName] (); }; return img; }; var toRight = mkTo ("toright", "transferRight"); var allToRight = mkTo ("alltoright", "transferAllRight"); var toLeft = mkTo ("toleft", "transferLeft"); var allToLeft = mkTo ("alltoleft", "transferAllLeft"); var center = dh.elt ("table", dh.elt ("tbody", dh.elt ("tr", dh.elt ("td", toRight)), dh.elt ("tr", dh.elt ("td", allToRight)), dh.elt ("tr", dh.elt ("td", toLeft)), dh.elt ("tr", dh.elt ("td", allToLeft)))); var c = dh.elt ( "div", dh.elt ( "table", dh.elt ( "tbody", dh.elt ("tr", dh.elt ("th", dh.txt ("Selected")), dh.elt ("th"), dh.elt ("th", dh.txt ("Available"))), dh.elt ("tr", dh.elt ("td.channelSelector", left), dh.elt ("td", center), dh.elt ("td.channelSelector", right))))); var transfer = new OptionTransfer (left, right); transfer.setAutoSort (false); // avoid sorting of items. c.getSelectedChannelsSelector = function () { return left; }; return c; }; /** * Make a new instance * ** This is the same as doing: *
var iaObj = ...; // get a IONIC.api.imagearchive.IAObject
var dh = ...; // get a IONIC.api.ui.DomHelper
var cpnt = IONIC.imagearchive.editors.GetCoverageChannelEditor.buildComponent (dh, iaObj);
var edtr = new IONIC.imagearchive.editors.GetCoverageChannelEditor (cpnt);
*
*
* @param {IONIC.api.ui.DomHelper} dh A dom helper to build the
* element
*
* @param {IONIC.api.imagearchive.IAObject} iaObj An object that's
* used to extract the channel info from.
*
* @return {IONIC.imagearchive.editors.GetCoverageChannelEditor}
*/
IONIC.imagearchive.editors.GetCoverageChannelEditor.newInstance = function (dh, iaObj) {
var cpnt = IONIC.imagearchive.editors.GetCoverageChannelEditor.buildComponent (dh, iaObj);
return new IONIC.imagearchive.editors.GetCoverageChannelEditor (cpnt);
};
/**
* Returns the selected channels as a coma-separated string.
*/
IONIC.imagearchive.editors.GetCoverageChannelEditor.prototype.getValues = function () {
var c = this.getComponent ();
var leftSelector = c.getSelectedChannelsSelector ();
var values = [];
IONIC.misc.forEach (function (option) {
values.push (option.value);
}, leftSelector.options);
return values.join (",");
};
/*extern IONIC,_root,YAHOO*/
/**
* @constructor
*
* @class
* An {@link IONIC.api.imagearchive.IAObject} is an object in the
* ImageArchive service.
*
* * Note: You shouldn't build these objects yourself, but * rather use, for example, the * {@link IONIC.api.imagearchive.ImageArchiveSearchPanel} search * capabilities for retrieving these objects. *
* * @param {IONIC.api.imagearchive.ServerRef} serverRef A reference to * the server this object belongs to * @param {string} name The name of the object * @param {string} title The title of the object * @param {enumeration} type The type of the object *({@link IONIC.api.imagearchive.IAObject.TYPE_GRANULE}, * {@link IONIC.api.imagearchive.IAObject.TYPE_AGGREGATE}) * @param {string} path The path in the hierarchy * @param {string} uuid The id of the corresponding catalogue object */ IONIC.api.imagearchive.IAObject = function (serverRef, name, title, type, path, uuid) { this._sr= serverRef; this._n = name; this._tt= title; this._t = type; this._p = path; this._kwds = []; this._wcsok = false; this._wmsok = false; this._uuid = uuid; }; /** * Build an axis set. * * @constructor * * @class * An {@link IONIC.api.imagearchive.IAObject.AxisSet} describes the * set of axes an {@link IONIC.api.imagearchive.IAObject} knows. * *
* The {@link IONIC.api.imagearchive.IAObject.AxisSet} type provides
* helper functions to handle the set of axes that can be used when
* performing a GetCoverage request.
*
* An axe has a name, a type * ( * {@link IONIC.api.imagearchive.IAObject.AxisSet.Axe#TYPE_RANGE} * or * {@link IONIC.api.imagearchive.IAObject.AxisSet.Axe#TYPE_ENUM}), * and an array of values. (in case the axe is of type range, the * array holds 2 values, which are the bounding minimum/maximum * values, and in case the axe is of type enumeration, the values * array holds N values, which are the enumeration entries) *
* * @param {string} name The name of the axe * * @param {int} type The type of the axe; either "range" or "enum" * * @param valuesType The type of the values, an entry in the * {@link IONIC.misc.PropertyType} enumeration * * @param values An array of values */ IONIC.api.imagearchive.IAObject.AxisSet.Axe = function (name, type, valuesType, values) { this._n = name; this._t = type; this._vt = valuesType; this._v = values.slice (); }; /** * An entry in the enumeration representing the type of axe. This * describes a "range" axe (with two values: minimum and maximum * bounds) */ IONIC.api.imagearchive.IAObject.AxisSet.Axe.TYPE_RANGE = 1; /** * An entry in the enumeration representing the type of axe. This * describes an "enum" axe (with N values) */ IONIC.api.imagearchive.IAObject.AxisSet.Axe.TYPE_ENUM = 2; /** * Get the name of this axe * * @return {string} the name */ IONIC.api.imagearchive.IAObject.AxisSet.Axe.prototype.getName = function () { return this._n; }; /** * Get the type of this axe * * @return {int} the type; an entry in the * IONIC.api.imagearchive.IAObject.AxisSet.Axe.TYPE_* enumeration. */ IONIC.api.imagearchive.IAObject.AxisSet.Axe.prototype.getType = function () { return this._t; }; /** * Get the array of values. * ** This array is not meant to be modified! *
* * @return the array of values */ IONIC.api.imagearchive.IAObject.AxisSet.Axe.prototype.getValues = function () { return this._v; }; /** * Get the data type of the entries in the array of values. * * @return the type of the values; an entry in the * {@link IONIC.misc.PropertyType} enumeration */ IONIC.api.imagearchive.IAObject.AxisSet.Axe.prototype.getValuesType = function () { return this._vt; }; /** * Build an {@link IONIC.api.imagearchive.IAObject.AxisSet.Axe} from a * JavaScript object holding the necessary properties. * * @param {object} tfa A transport-formatted object holding the * information for building an * {@link IONIC.api.imagearchive.IAObject.AxisSet.Axe} * * @return {IONIC.api.imagearchive.IAObject.AxisSet.Axe} an axe object * * @private */ IONIC.api.imagearchive.IAObject.AxisSet.Axe.fromTransportFormat = function (tfa) { var axe = new IONIC.api.imagearchive.IAObject.AxisSet.Axe ( tfa.name, IONIC.api.imagearchive.IAObject.AxisSet.Axe.typeStringToType (tfa.type), tfa.valuesType, tfa.values); return axe; }; /** * @ignore */ IONIC.api.imagearchive.IAObject.AxisSet.Axe.TYPE_MAPPING = { "enumeration" : IONIC.api.imagearchive.IAObject.AxisSet.Axe.TYPE_ENUM, "range" : IONIC.api.imagearchive.IAObject.AxisSet.Axe.TYPE_RANGE }; /** * @private */ IONIC.api.imagearchive.IAObject.AxisSet.Axe.typeStringToType = function (typeString) { var t = IONIC.api.imagearchive.IAObject.AxisSet.Axe.TYPE_MAPPING [typeString]; if (! t) { throw "Unexpected axe type: " + typeString; } return t; }; /** * Get the axe that's used to select what bands/axes to retrieve in a *GetCoverage request.
*
* @return {IONIC.api.imagearchive.IAObject.AxisSet.Axe} the channel
* axe, or undefined if none present
*/
IONIC.api.imagearchive.IAObject.AxisSet.prototype.getChannelAxe = function () {
return this._chanAxe;
};
/**
* Set the axe that's used to select what bands/axes to retrieve in a
* GetCoverage request.
*
* @param {IONIC.api.imagearchive.IAObject.AxisSet.Axe} axe The
* channel axe
*
* @private
*/
IONIC.api.imagearchive.IAObject.AxisSet.prototype.setChannelAxe = function (axe) {
this._chanAxe = axe;
};
/**
* Get the axe that represents the null range.
*
* * The "null" range, is the range of values that correspond to * transparency in an image (in case the image is requested through * WMS interface, or in empty data, in case the coverage is * requested through WCS interface *
* * @return {IONIC.api.imagearchive.IAObject.AxisSet.Axe} the null * axe, or undefined if none present */ IONIC.api.imagearchive.IAObject.AxisSet.prototype.getNullAxe = function () { return this._nullAxe; }; /** * Set the axe that represents the null range. * * @param {IONIC.api.imagearchive.IAObject.AxisSet.Axe} axe The * channel axe * @private */ IONIC.api.imagearchive.IAObject.AxisSet.prototype.setNullAxe = function (axe) { this._nullAxe = axe; }; /** * Get every axe but the "channel" nor the "null" ones. * * @return {IONIC.api.imagearchive.IAObject.AxisSet.Axe[]} an array of * axes */ IONIC.api.imagearchive.IAObject.AxisSet.prototype.getOtherAxes = function () { return this._otherAxes; }; /** * Set the axes but the "channel" nor the "null" ones. * * @param {IONIC.api.imagearchive.IAObject.AxisSet.Axe[]} axes An * array of axes. * @private */ IONIC.api.imagearchive.IAObject.AxisSet.prototype.setOtherAxes = function (axes) { this._otherAxes = axes.slice (); }; /** * Build an {@link IONIC.api.imagearchive.IAObject.AxisSet} from a * JavaScript object holding the necessary properties. * * @param {object} tfas A transport-formatted object holding the * information for building an * {@link IONIC.api.imagearchive.IAObject.AxisSet} * * @return {IONIC.api.imagearchive.IAObject.AxisSet} an axe object * * @private */ IONIC.api.imagearchive.IAObject.AxisSet.fromTransportFormat = function (tfas) { var axisSet = new IONIC.api.imagearchive.IAObject.AxisSet (); if (tfas.channelAxis) { axisSet.setChannelAxe ( IONIC.api.imagearchive.IAObject.AxisSet.Axe.fromTransportFormat ( tfas.channelAxis)); } if (tfas.nullAxis) { axisSet.setNullAxe ( IONIC.api.imagearchive.IAObject.AxisSet.Axe.fromTransportFormat ( tfas.nullAxis)); } if (tfas.otherAxes) { axisSet.setOtherAxes ( IONIC.misc.mapcar1 (function (tfa) { return IONIC.api.imagearchive.IAObject.AxisSet.Axe.fromTransportFormat ( tfa); }, tfas.otherAxes)); } return axisSet; }; /** * An enumeration entry for the granule type */ IONIC.api.imagearchive.IAObject.TYPE_GRANULE = 1; /** * An enumeration entry for the aggregate type */ IONIC.api.imagearchive.IAObject.TYPE_AGGREGATE = 2; /** * Get the reference to the server this object belongs to. * * @return {IONIC.api.imagearchive.ServerRef} the server reference */ IONIC.api.imagearchive.IAObject.prototype.getServerRef = function () { return this._sr; }; /** * Get the name of the object * ** The name is the ID of the object, as it is unique in an * ImageArchive server instance. *
* * @return {string} the name */ IONIC.api.imagearchive.IAObject.prototype.getName = function () { return this._n; }; /** * Get the uuid of the object * ** The uuid of the object in the catalogue server. *
* * @return {string} the uuid */ IONIC.api.imagearchive.IAObject.prototype.getId = function () { return this._uuid; }; /** * Get the title of the object * * @return {string} the title */ IONIC.api.imagearchive.IAObject.prototype.getTitle = function () { return this._tt; }; /** * Get the type of the object * * @return {enumeration} the type ( * {@link IONIC.api.imagearchive.IAObject.TYPE_GRANULE}, ...) */ IONIC.api.imagearchive.IAObject.prototype.getType = function () { return this._t; }; /** * Is this object a granule? * * @return {boolean}true if this is an object of the
* {@link IONIC.api.imagearchive.TYPE_GRANULE} type
*/
IONIC.api.imagearchive.IAObject.prototype.isGranule = function () {
return this.getType () === IONIC.api.imagearchive.IAObject.TYPE_GRANULE;
};
/**
* Is this object an aggregate?
*
* @return {boolean} true if this is an object of the
* {@link IONIC.api.imagearchive.TYPE_AGGREGATE} type
*/
IONIC.api.imagearchive.IAObject.prototype.isAggregate = function () {
return this.getType () === IONIC.api.imagearchive.IAObject.TYPE_AGGREGATE;
};
/**
* Get the path of the object, in the hierarchy tree.
*
* @return {string} the path
*/
IONIC.api.imagearchive.IAObject.prototype.getPath = function () {
return this._p;
};
/**
* Set the keywords for this object
*
* @param {string[]} keywords The keywords
*/
IONIC.api.imagearchive.IAObject.prototype.setKeywords = function (keywords) {
this._kwds = keywords ? keywords.slice () : [];
};
/**
* Get the keywords for this object
*
* @return {string[]} the keywords
*/
IONIC.api.imagearchive.IAObject.prototype.getKeywords = function () {
return this._kwds.slice ();
};
/**
* Set the WMS-availability of this object
*
* @param {boolean} flag A flag
* @private
*/
IONIC.api.imagearchive.IAObject.prototype.setAvailabilityWMS = function (flag) {
this._wmsok = flag;
};
/**
* Set the WCS-availability of this object
*
* @param {boolean} flag A flag
* @private
*/
IONIC.api.imagearchive.IAObject.prototype.setAvailabilityWCS = function (flag) {
this._wcsok = flag;
};
/**
* Is this object available as WMS?
*
* @return {boolean} true if this object is available as
* WMS
*/
IONIC.api.imagearchive.IAObject.prototype.isAvailableAsWMS = function () {
return this._wmsok;
};
/**
* Is this object available as WCS?
*
* @return {boolean} true if this object is available as
* WCS
*/
IONIC.api.imagearchive.IAObject.prototype.isAvailableAsWCS = function () {
return this._wcsok;
};
/**
* Is this object available as streamed raster?
*
* * For a coverage to be available as streamed raster (i.e., ECWP, * JP2, ...), it is necessary that its decoder be "ECW" or "JP2". *
* * @return {boolean}true if this object is available as
* streamed raster
*/
IONIC.api.imagearchive.IAObject.prototype.isAvailableAsStreamedRaster = function () {
var streamingEnabled = "false" === "true";
var dn = (this.getDecoderName () || "").toUpperCase ();
return streamingEnabled && ("ECW" === dn || "JP2" === dn);
};
/**
* Set the spatial extent for this object
*
* @param geom A geometry, from the {@link IONIC.api.geom} package.
* @private
*/
IONIC.api.imagearchive.IAObject.prototype.setSpatialExtent = function (geom) {
this._geom = geom;
};
/**
* Get the spatial extent for this object
*
* @return a geometry, from the {@link IONIC.api.geom} package, or
* undefined if none
*/
IONIC.api.imagearchive.IAObject.prototype.getSpatialExtent = function () {
return this._geom;
};
/**
* Set the temporal extent for this object
*
* @param tempExtent ...
* @private
*/
IONIC.api.imagearchive.IAObject.prototype.setTemporalExtent = function (tempExtent) {
this._tempExtent = tempExtent;
};
/**
* Get the temporal extent for this object
*
* @return the temporal extent, or undefined if none
*/
IONIC.api.imagearchive.IAObject.prototype.getTemporalExtent = function () {
return this._tempExtent;
};
/**
* Set all the native bounding boxes that were defined for this
* object.
*
* @param {IONIC.api.geom.Box[]} bboxes The array of bounding boxes
*
* @private
*/
IONIC.api.imagearchive.IAObject.prototype.setDefinedBoundingBoxes = function (bboxes) {
this.bboxes = bboxes;
};
/**
* Get all the native bounding boxes that were defined for this
* object.
*
* * The returned array is not meant to be modified. *
* * @return {IONIC.api.geom.Box[]} the array of bounding boxes */ IONIC.api.imagearchive.IAObject.prototype.getDefinedBoundingBoxes = function () { return this.bboxes || []; }; /** * Set the children information for this object * * @param {object[]} childrenInfos The objects holding information * about the children. * @private */ IONIC.api.imagearchive.IAObject.prototype.setChildrenInfos = function (childrenInfos) { this._ci = childrenInfos; }; /** * Get the children information for this object * * @return {object[]} an array of objects having at least the * following property:name
*/
IONIC.api.imagearchive.IAObject.prototype.getChildrenInfos = function () {
return this._ci;
};
/**
* Build the URL for fetching, as an image, the thumbnail
* corresponding to this object with the given name.
*
* @param {int} width (optional) The width, in pixels, of the
* thumbnail. Defaults to
* {@link IONIC.imagearchive.ImageArchiveTool.DEFAULT_THUMBNAIL_WIDTH}.
* @param {int} height (optional) The height, in pixels, of the
* thumbnail. Defaults to
* {@link IONIC.imagearchive.ImageArchiveTool.DEFAULT_THUMBNAIL_HEIGHT}.
*
* @see IONIC.imagearchive.ImageArchiveTool#getThumbnailUrl
* @see IONIC.api.imagearchive.IAObject#loadThumbnailInImage
*/
IONIC.api.imagearchive.IAObject.prototype.getThumbnailUrl = function (width, height) {
return (new IONIC.imagearchive.ImageArchiveTool (this.getServerRef ())).
getThumbnailUrl (
this.getName (),
width,
height);
};
/**
* Set the {@link IONIC.api.imagearchive.IAObject.AxisSet} for this
* object.
*
* @param {IONIC.api.imagearchive.IAObject.AxisSet} axisSet The axis
* set
*/
IONIC.api.imagearchive.IAObject.prototype.setAxisSet = function (axisSet) {
this._axisSet = axisSet;
};
/**
* Get the {@link IONIC.api.imagearchive.IAObject.AxisSet} for this
* object.
*
* @return {IONIC.api.imagearchive.IAObject.AxisSet} the axis
* set
*/
IONIC.api.imagearchive.IAObject.prototype.getAxisSet = function () {
return this._axisSet;
};
/**
* Set the EPSG IDs in which a GetCoverage operation can
* be performed on the ImageArchive, for this object.
*
* @param {int[]} srses The epsg IDs of the supported input srses
*
* @see #getGetCoverageRequestSRSes
*
* @private
*/
IONIC.api.imagearchive.IAObject.prototype.setGetCoverageRequestSRSes = function (srses) {
this._getCovReqSrses = srses.slice ();
};
/**
* Get the array of EPSG IDs a GetCoverage operation
* supports in input, for this object.
*
* * The returned array is not meant to be modified. *
* * @return {int[]} the supported epsg IDs */ IONIC.api.imagearchive.IAObject.prototype.getGetCoverageRequestSRSes = function () { return this._getCovReqSrses || []; }; /** * Set the EPSG IDs in which the results of a *GetCoverage operation can be expressed, for this
* object.
*
* @param {int[]} srses The epsg IDs of the supported output srses
*
* @see #getGetCoverageResponseSRSes
*
* @private
*/
IONIC.api.imagearchive.IAObject.prototype.setGetCoverageResponseSRSes = function (srses) {
this._getCovRespSrses = srses.slice ();
};
/**
* Get the array of EPSG IDs a GetCoverage operation
* supports in output, for this object.
*
* * The returned array is not meant to be modified. *
* * @return {int[]} the supported epsg IDs */ IONIC.api.imagearchive.IAObject.prototype.getGetCoverageResponseSRSes = function () { return this._getCovRespSrses || []; }; /** * Set the list of formats supported by theGetCoverage
* request, for this object.
*
* @param {string[]} formats The coverage formats
*
* @see #getCoverageTypes
*
* @private
*/
IONIC.api.imagearchive.IAObject.prototype.setCoverageTypes = function (formats) {
this._covTypes = formats.slice ();
};
/**
* Set the list of formats supported by the GetCoverage
* request, for this object.
*
* * The returned array is not meant to be modified. *
* * @return {string[]} the supported coverage formats/types. */ IONIC.api.imagearchive.IAObject.prototype.getCoverageTypes = function () { return this._covTypes || []; }; /** * Set the list of interpolation methods supported by the *GetCoverage request, for this object.
*
* @param {string[]} interps The interpolation methods
*
* @see #getInterpolationMethods
*
* @private
*/
IONIC.api.imagearchive.IAObject.prototype.setInterpolationMethods = function (interps) {
this._interps = interps.slice ();
};
/**
* Get the list of interpolation methods supported by the
* GetCoverage request, for this object.
*
* * The returned array is not meant to be modified. *
* * @return {string[]} the supported interpolation methods. */ IONIC.api.imagearchive.IAObject.prototype.getInterpolationMethods = function () { return this._interps || []; }; /** * Set the 'key-value pairs' field. * * @param {Array} kvPairs The key-value pairs * * @see #getKeyValuePairs * * @private */ IONIC.api.imagearchive.IAObject.prototype.setKeyValuePairs = function (kvPairs) { this._kvPairs = kvPairs; }; /** * Gets the key-value pairs. * ** The returned array is not meant to be modified. *
* * @return {Array} the key-value pairs, or undefined if not set. */ IONIC.api.imagearchive.IAObject.prototype.getKeyValuePairs = function () { return this._kvPairs; }; /** * Set the decoder name. * * @param {string} decoderName The decoder name * * @see #getDecoderName * * @private */ IONIC.api.imagearchive.IAObject.prototype.setDecoderName = function (decoderName) { this.decoderName = decoderName; }; /** * Gets the decoder name. * * @return {string} the decoder name */ IONIC.api.imagearchive.IAObject.prototype.getDecoderName = function () { return this.decoderName; }; /** * Set the file URI (only makes sense for granules, not aggregates). * * @param {string} fileUri The file URI * * @see #getFileURI * * @private */ IONIC.api.imagearchive.IAObject.prototype.setFileURI = function (fileUri) { this.fileUri = fileUri; }; /** * Gets the file URI (only makes sense for granules, not aggregates). * * @return {string} the file URI */ IONIC.api.imagearchive.IAObject.prototype.getFileURI = function () { return this.fileUri; }; /** * Set the metadata URL. * * @param {string} metadata The URL for metadata */ IONIC.api.imagearchive.IAObject.prototype.setMetadataUrl = function (metadata) { this.metadata = metadata; }; /** * Gets the metadata URL. * * @return {string} The metadata URL. */ IONIC.api.imagearchive.IAObject.prototype.getMetadataUrl = function () { return this.metadata; }; /** * Loads the thumbnail for this object in the given image. * *
* This will set an onerror handler on the
* <img>, that will be called if the given
* object has no thumbnail, in order to display a nice
* "thumbnail unavailable"-like image, rather than an ugly broken
* image.
*
* This renderer will create mouse-sensitive rows that, when * hovered, will display a popup with the object information. *
** In case the parent * {@link IONIC.api.imagearchive.TableResultsHandler} has an * associated {@link IONIC.api.maps.Map}, it will also display the * geometry of the objects on the map. *
** In case the parent * {@link IONIC.api.imagearchive.TableResultsHandler} has an * associated * {@link IONIC.api.imagearchive.ImageArchiveGetCoveragePanel}, it * will also display, for each result that can be retrieved through * the panel, an icon to import it into the panel for retrieval. *
*/ IONIC.api.imagearchive.DefaultTableRowRenderer = function () { }; IONIC.misc.extendType (IONIC.api.imagearchive.DefaultTableRowRenderer, IONIC.ui.AbstractObjectRenderer); /** * Create an HTML <tr>, ready to be embedded in the * {@link IONIC.api.imagearchive.TableResultsHandler}'s current page's * <table> * * @param {IONIC.api.imagearchive.TableResultsHandler} * parentResultsHandler The instance of * {@link IONIC.api.imagearchive.TableResultsHandler} that called * this renderer * @param {IONIC.api.imagearchive.IAObject} iaobj An object in the * ImageArchive server * @return {HTMLTrElement} the <tr> to be embedded into the * parent {@link IONIC.api.imagearchive.TableResultsHandler} */ IONIC.api.imagearchive.DefaultTableRowRenderer.prototype.render = function (parentResultsHandler, iaobj) { var dh = parentResultsHandler.getDomHelper (); var typeImg = dh.elt ("img"); typeImg.src = IONIC.misc.getWebappBaseUrl () + "/images/imagearchive/search/" + (iaobj.isAggregate () ? "aggregate" : "granule") + (IONIC.api.imagearchive.DefaultTableRowRenderer.useSmallIcons ? "-small" : "") + ".gif"; var addedToMapElt = dh.elt ("span.addedToMapMarker"); var titleElt = dh.elt ("td", addedToMapElt, dh.txt (iaobj.getName ())); var row = dh.elt ( "tr.resultEntry", dh.elt ("td", typeImg), // type (aggregate/granule) titleElt); titleElt.displayedObject = iaobj; titleElt.displayedObjectHolder = { iaObject: iaobj, getIAObject: function (callback, full) { // Not implemented: taking care of 'full' argument. It should not be necessary callback(iaobj); } }; titleElt.onclick = function () { SearchModule.getDetailPanel ().renderDetailsByName (iaobj.getName ()); }; if (this.htmlDecorator) { this.htmlDecorator.addElements ([titleElt]); } var importCov; var getCoveragePanel = parentResultsHandler.getAssociatedGetCoveragePanel (); if (getCoveragePanel) { if (iaobj.isAvailableAsWCS ()) { importCov = dh.elt ("input.importCoverage"); importCov.type = "button"; importCov.value = "Get coverage"; importCov.onclick = function () { getCoveragePanel.loadCoverageDescriptionByName (iaobj.getName ()); }; dh.append (row, dh.elt ("td", importCov)); } else { dh.append (row, dh.elt ("td", dh.txt (" "))); } } var displayMap = parentResultsHandler.getAssociatedDisplayMap (); if (displayMap) { if (iaobj.isAvailableAsWMS ()) { importCov = dh.elt ("input.importCoverage"); importCov.type = "button"; importCov.value = "Add to map"; importCov.onclick = function () { displayMap.addCoverage (iaobj); }; dh.append (row, dh.elt ("td", importCov)); } else { dh.append (row, dh.elt ("td", dh.txt (" "))); } } var self = this; row.onmouseover = function (e) { var popup = self.retrieveHoverPopup (parentResultsHandler, parentResultsHandler.getAssociatedMap ()); IONIC.api.imagearchive.DefaultTableRowRenderer.onMouseOverHandler (popup, iaobj); e = e || event; var evt = JSToolbox.Event; var mx = evt.getMouseX (e); var my = evt.getMouseY (e); }; row.onmouseout = function (e) { e = e || event; var popup = self.retrieveHoverPopup (parentResultsHandler, parentResultsHandler.getAssociatedMap ()); IONIC.api.imagearchive.DefaultTableRowRenderer.onMouseOutHandler (popup); }; this.renderFootprint (iaobj); return row; }; /** * Adds a 'decorator', i.e. an object that can be aware of the generation of HTML elements * representing an ImageArchive object. * @param {object} htmlDecorator The decorator. It must have two properties: addElements * that is a function with one argument: an array of HTMLElements. Each such HTML element * will have a iaObjectName (string) property and an optional iaObject * (object) property. The second property is deleteElement, which is symetrical to * addElements and take the same argument. */ IONIC.api.imagearchive.DefaultTableRowRenderer.prototype.setHtmlDecorator = function (htmlDecorator) { this.htmlDecorator = htmlDecorator; }; /** * @private */ IONIC.api.imagearchive.DefaultTableRowRenderer.onMouseOverHandler = function (popup, iaobj) { popup.setContent (iaobj); popup.show (); }; /** * @private */ IONIC.api.imagearchive.DefaultTableRowRenderer.onMouseOutHandler = function(popup) { popup.hide (); }; /** * @ignore */ IONIC.api.imagearchive.DefaultTableRowRenderer.POPUPTIMEOUT = 300; /** * Get the <div>, that will be used as a popup, displaying * information about the result. * * @param {IONIC.misc.AbstractResultsHandler} parentResultsHandler The * instance of {@link IONIC.misc.AbstractResultsHandler} that called * this renderer * @return {HTMLDivElement} * @private */ IONIC.api.imagearchive.DefaultTableRowRenderer.prototype.retrieveHoverPopup = function (parentResultsHandler, map) { var dh, s; if (! parentResultsHandler.hoverPopup) { dh = parentResultsHandler.getDomHelper (); parentResultsHandler.hoverPopup = new IONIC.api.imagearchive.IAObjectPopup(dh, null, map); parentResultsHandler.hoverPopup.setDelay(IONIC.api.imagearchive.DefaultTableRowRenderer.POPUPTIMEOUT); } return parentResultsHandler.hoverPopup; }; /** * Draws the footprint of the object. Requires a layer to draw the footprint to; see {@link #setFootprintLayer}. * * @param {IONIC.api.imagearchive.IAObject} iaObject The object to depict. * @private */ IONIC.api.imagearchive.DefaultTableRowRenderer.prototype.renderFootprint = function (iaObject) { if (!this.footprintLayer || !iaObject.getSpatialExtent ()) { return; } var drawingOptions = iaObject.isAggregate () ? IONIC.api.imagearchive.DefaultTableRowRenderer.FOOTPRINT_AGGREGATE_DRAWING_OPTIONS : IONIC.api.imagearchive.DefaultTableRowRenderer.FOOTPRINT_GRANULE_DRAWING_OPTIONS; this.footprintLayer.addGeometry (iaObject.getSpatialExtent (), drawingOptions); }; /** * Allows to add a {@link IONIC.geom.edit.GEditLayerDescriptor} layer that will be used to draw the * footprint of each result. * * @param {IONIC.geom.edit.GEditLayerDescriptor} layer The layer. */ IONIC.api.imagearchive.DefaultTableRowRenderer.prototype.setFootprintLayer = function (layer) { this.footprintLayer = layer; }; IONIC.api.imagearchive.DefaultTableRowRenderer.FOOTPRINT_GRANULE_DRAWING_OPTIONS = new IONIC.api.maps.Map.DrawingOptions(.5, "#880000", .5); IONIC.api.imagearchive.DefaultTableRowRenderer.FOOTPRINT_AGGREGATE_DRAWING_OPTIONS = new IONIC.api.maps.Map.DrawingOptions(.5, "#880000", .7); /** * @private */ IONIC.api.imagearchive.DefaultTableRowRenderer.useSmallIcons = true; /** * @constructor * * @class * This default implementation of a * {@link IONIC.ui.AbstractObjectRenderer} will * create <tr>, and therefore * is meant to be used with a * {@link IONIC.api.imagearchive.TableResultsHandler}. It renders objects * returned by a search * * @extends IONIC.ui.AbstractObjectRenderer * ** This renderer will create mouse-sensitive rows that, when * hovered, will display a popup with the object information. *
** In case the parent * {@link IONIC.api.imagearchive.TableResultsHandler} has an * associated {@link IONIC.api.maps.Map}, it will also display the * geometry of the objects on the map. *
** In case the parent * {@link IONIC.api.imagearchive.TableResultsHandler} has an * associated * {@link IONIC.api.imagearchive.ImageArchiveGetCoveragePanel}, it * will also display, for each result that can be retrieved through * the panel, an icon to import it into the panel for retrieval. *
*/ IONIC.api.imagearchive.WfsTableRowRenderer = function () { this.htmlDecorator = null; }; IONIC.misc.extendType (IONIC.api.imagearchive.WfsTableRowRenderer, IONIC.ui.AbstractObjectRenderer); /** * Create an HTML <tr>, ready to be embedded in the * {@link IONIC.api.imagearchive.TableResultsHandler}'s current page's * <table>. * * @param {IONIC.api.imagearchive.TableResultsHandler} * parentResultsHandler The instance of * {@link IONIC.api.imagearchive.TableResultsHandler} that called * this renderer * * @param {object} wfsObject An object describing a WFS service. * * @return {HTMLTrElement} the <tr> to be embedded into the * parent {@link IONIC.api.imagearchive.TableResultsHandler} */ IONIC.api.imagearchive.WfsTableRowRenderer.prototype.render = function (parentResultsHandler, wfsObject) { var dh = parentResultsHandler.getDomHelper (); var typeImg = dh.elt ("img"); typeImg.src = IONIC.misc.getWebappBaseUrl () + "/images/imagearchive/search/wfs" + (IONIC.api.imagearchive.DefaultTableRowRenderer.useSmallIcons ? "-small" : "") + ".gif"; var displayMap = parentResultsHandler.getAssociatedDisplayMap (); var iaTool = parentResultsHandler.getAssociatedIATool (); var titleElt = dh.elt ("td", dh.txt (wfsObject.name)); var row = dh.elt ("tr", dh.elt ("td", typeImg), titleElt); if (this.htmlDecorator) { titleElt.wfsObject = wfsObject; this.htmlDecorator.addElements ([titleElt]); } if (iaTool) { var iso19115Button = this.makeIso19115Button (dh, iaTool, wfsObject); dh.append (row, dh.elt ("td", iso19115Button)) } if (displayMap && wfsObject.wmsUrl) { var wmsButton = this.makeWmsButton (dh, wfsObject, displayMap); dh.append (row, dh.elt ("td", wmsButton)); } if (displayMap && wfsObject.wfsUrl) { var wfsButton = this.makeWfsButton (dh, wfsObject, displayMap); dh.append (row, dh.elt ("td", wfsButton)); } row.onmouseover = function (e) { e = e || event; row.popup = new IONIC.api.imagearchive.WfsPopup (dh, wfsObject, displayMap); row.popup.show (); }; row.onmouseout = function (e) { e = e || event; if (row.popup) { row.popup.destroy (); row.popup = null; } }; return row; }; /** * Adds a 'decorator', i.e. an object that can be aware of the generation of HTML elements * representing WFS service. * @param {object} htmlDecorator The decorator. It must have two properties: addElements * that is a function with one argument: an array of HTMLElements. Each such HTML element * will have a wfsObject (object) property. The second property is deleteElement, * which is symetrical to addElements and take the same argument. */ IONIC.api.imagearchive.WfsTableRowRenderer.prototype.setHtmlDecorator = function (htmlDecorator) { this.htmlDecorator = htmlDecorator; }; /** * Builds the 'add WFS as WMS to map' button. * * @param {IONIC.api.ui.DomHelper} dh A dom helper. * @param {object} wfsObject The object representing the WFS service. * @param {IONIC.api.imagearchive.ImageArchiveMap} The map where the WFS should be added. * * @private */ IONIC.api.imagearchive.WfsTableRowRenderer.prototype.makeWmsButton = function (dh, wfsObject, displayMap) { wmsButton = dh.elt ("input.wfsToMapAsWms"); wmsButton.type = "button"; wmsButton.value = "Add to map as WMS"; wmsButton.onclick = function () { displayMap.addWMSLayers (wfsObject.wmsUrl, wfsObject.layerName); } return wmsButton; }; /** * Builds the 'add WFS as WFS to map' button. * * @param {IONIC.api.ui.DomHelper} dh A dom helper. * @param {object} wfsObject The object representing the WFS service. * @param {IONIC.api.imagearchive.ImageArchiveMap} The map where the WFS should be added. * * @private */ IONIC.api.imagearchive.WfsTableRowRenderer.prototype.makeWfsButton = function (dh, wfsObject, displayMap) { wfsButton = dh.elt ("input.wfsToMapAsWms"); wfsButton.type = "button"; wfsButton.value = "Add to map"; wfsButton.onclick = function () { var providerDiscovery = new IONIC.api.maps.ProviderDiscoveryTool (displayMap); providerDiscovery.withAddedWFSLayers (wfsObject.wfsUrl, [ wfsObject.layerName ]); } return wfsButton; }; /** * Builds the 'add WFS as WMS to map' button. * * @param {IONIC.api.ui.DomHelper} dh A dom helper. * @param {IONIC.imagearchive.ImageArchiveTool} The tool used to access metadata. * @param {object} wfsObject The object representing the WFS service. * * @private */ IONIC.api.imagearchive.WfsTableRowRenderer.prototype.makeIso19115Button = function (dh, iaTool, wfsObject) { isoButton = dh.elt ("input.wfsIso19115"); isoButton.type = "button"; isoButton.value = "ISO19115"; isoButton.onclick = function () { open (iaTool.getWfsISO19115SearchUrl(wfsObject.id), "ISO19115", "width=600,height=400,scrollbars=1,resizable=1"); } return isoButton; }; /** * @private */ IONIC.api.imagearchive.WfsTableRowRenderer.useSmallIcons = IONIC.api.imagearchive.DefaultTableRowRenderer.useSmallIcons; /** * @constructor * * @class * A {@link IONIC.api.imagearchive.TableResultsHandler} can be passed * to the {@link IONIC.api.imagearchive.ImageArchiveSearchPanel} and * handles the results from a search on an image archive server. * ** This handler builds a notebook, with each page of which holding a * <table> with the results. The table * is filled with the <tr> produced by the * {@link IONIC.ui.AbstractObjectRenderer} *
** If the renderer is unspecified, instance of this type will use a * {@link IONIC.api.imagearchive.DefaultTableRowRenderer} * to render the results. If you want to override the default * behaviour, you'll need to provide your own * {@link IONIC.ui.AbstractObjectRenderer}. *
* * @extends IONIC.api.ui.NotebookResultsHandler * * @param {HTMLElement} htmlElt The HTML element (or it's ID) in which * the table will be built * @param {IONIC.api.ui.DomHelper} dh A dom helper instance * @param {IONIC.ui.AbstractObjectRenderer} renderer (optional) A * renderer to use for the results * @param {int} itemsPerPage (optional) The number of items per page */ IONIC.api.imagearchive.TableResultsHandler = function (htmlElt, dh, renderer, itemsPerPage) { var self = this; IONIC.api.ui.NotebookResultsHandler.call (this, htmlElt, dh, renderer || new IONIC.api.imagearchive.DefaultTableRowRenderer (), itemsPerPage); }; IONIC.misc.extendType (IONIC.api.imagearchive.TableResultsHandler, IONIC.api.ui.NotebookResultsHandler); /** * Create a <table> to be the top element of a page * * @return {HTMLTableElement} the table */ IONIC.api.imagearchive.TableResultsHandler.prototype.createPageContents = function () { var dh = this.getDomHelper (); return dh.elt ("table", dh.elt ("tbody")); }; /** * Injects the HTML fragment in the tab view's container. * * @param {YAHOO.widget.Tab} tab The current page * @param {HTMLElement} html The HTML to be embedded into the page */ IONIC.api.imagearchive.TableResultsHandler.prototype.injectHTMLResult = function (tab, html) { var dh = this.getDomHelper (); var table = tab.hackGetContents (); var tbd = table.getElementsByTagName ("tbody") [0]; dh.append (tbd, html); }; /** * Get the {@link IONIC.api.maps.Map} that is associated to this * instance. * * @return {IONIC.api.maps.Map} the associated map */ IONIC.api.imagearchive.TableResultsHandler.prototype.getAssociatedMap = function () { return this._map; }; /** * Set the {@link IONIC.api.maps.Map} that is associated to this * instance. * ** Attaching a {@link IONIC.api.maps.Map} to an instance of this * type will allow the delegate types to work with it. In other * words, take the * {@link IONIC.api.imagearchive.DefaultTableRowRenderer} for * example: If it finds a map associated to this results handler, it * will be able to show the geometries of the objects on the * map. Ain't that cool? *
* * @param {IONIC.api.maps.Map} map The map to be associated to this * instance. */ IONIC.api.imagearchive.TableResultsHandler.prototype.setAssociatedMap = function (map) { this._map = map; }; /** * Get the {@link IONIC.api.imagearchive.ImageArchiveGetCoveragePanel} * that is associated to this instance. * * @return {IONIC.api.imagearchive.ImageArchiveGetCoveragePanel} the * associated "GetCoverage" panel */ IONIC.api.imagearchive.TableResultsHandler.prototype.getAssociatedGetCoveragePanel = function () { return this._covPanel; }; /** * Set the {@link IONIC.api.imagearchive.ImageArchiveGetCoveragePanel} * that is associated to this instance. * ** Attaching a * {@link IONIC.api.imagearchive.ImageArchiveGetCoveragePanel} to an * instance of this type will allow the delegate types to work with * it. In other words, take the * {@link IONIC.api.imagearchive.DefaultTableRowRenderer} for * example: If it finds a GetCoverage associated to this results * handler, the results will be retrievable through that panel. *
* * @param {IONIC.api.imagearchive.ImageArchiveGetCoveragePanel} * coveragePanel The panel */ IONIC.api.imagearchive.TableResultsHandler.prototype.setAssociatedGetCoveragePanel = function (coveragePanel) { this._covPanel = coveragePanel; }; /** * Get the {@link IONIC.api.maps.Map} that is associated to this instance. This map is used to * display coverages. * * @return {IONIC.api.maps.Map} the associated display map. */ IONIC.api.imagearchive.TableResultsHandler.prototype.getAssociatedDisplayMap = function () { return this._displayMap; }; /** * Set the {@link IONIC.api.maps.Map} that is associated to this instance. This map is used to * display coverages. * * @param {IONIC.api.maps.Map} map The map to use to display coverages */ IONIC.api.imagearchive.TableResultsHandler.prototype.setAssociatedDisplayMap = function (map) { this._displayMap = map; }; /** * Get the {@link IONIC.imagearchive.ImageArchiveTool} that is associated to this instance. * It can be used to fetch information related to the displayed results, such as metadata. * * @return {IONIC.imagearchive.ImageArchiveTool} the associated display map. * @private */ IONIC.api.imagearchive.TableResultsHandler.prototype.getAssociatedIATool = function () { return this._iaTool; }; /** * Set the {@link IONIC.imagearchive.ImageArchiveTool} that is associated to this instance. * It can be used to fetch information related to the displayed results, such as metadata. * * @param {IONIC.imagearchive.ImageArchiveTool} iaTool The tool used to access remote data. * @private */ IONIC.api.imagearchive.TableResultsHandler.prototype.setAssociatedIATool = function (iaTool) { this._iaTool = iaTool; }; /* * Copyright 2005- by IONIC Software S.A., * 18 Av Wallonie, 4460 Grace-Hollogne, Belgium. * All rights reserved. * * This software is the confidential and proprietary information * of IONIC Software S.A.("Confidential Information"). * You shall not disclose such Confidential Information and shall use * it only in accordance with the terms of the license agreement * you entered into with IONIC Software. */ /** * @constructor * * @class * * A {@link IONIC.api.imagearchive.ImageArchiveSearchPanel} holds an * HTML element with the necessary editors for the different search * criteria provided by an image archive server. * * @extends IONIC.imagearchive.AbstractImageArchivePanel * * @param {HTMLElement} htmlElt The containing HTML element, or it's * ID. * @param {IONIC.api.imagearchive.ServerRef} serverRef A reference to * the image archive server * @param {HTMLWindow} win (Optional) The window in which is the * document holding the element named "htmlElt", if "htmlElt" is * a string (defaults to the current window). */ IONIC.api.imagearchive.ImageArchiveSearchPanel = function (htmlElt, serverRef, win) { IONIC.imagearchive.AbstractImageArchivePanel.call (this, htmlElt, serverRef, win); var dh = this.getDomHelper (); this._cpnt = dh.elt ("div"); dh.append (htmlElt, this._cpnt); this.buildComponent (); var self = this; this.withImageArchiveCustomQueryables (function (queryables) { self.addCustomQueryables (queryables); self.updateVisibleFields (); }); }; IONIC.misc.extendType (IONIC.api.imagearchive.ImageArchiveSearchPanel, IONIC.imagearchive.AbstractImageArchivePanel); /** * The name of the editor for the keywords criterion */ IONIC.api.imagearchive.ImageArchiveSearchPanel.ED_KEYWORDS = "kwds"; /** * The name of the editor for the availability criterion */ IONIC.api.imagearchive.ImageArchiveSearchPanel.ED_AVAILABILITY = "avail"; /** * The name of the editor for the type criterion */ IONIC.api.imagearchive.ImageArchiveSearchPanel.ED_TYPE = "type"; /** * The name of the editor for the bounding box criterion */ IONIC.api.imagearchive.ImageArchiveSearchPanel.ED_BBOX = "bbox"; /** * The name of the editor for the timestamp boundaries criterion */ IONIC.api.imagearchive.ImageArchiveSearchPanel.ED_TIMESTAMP = "ts"; /** * The name of the editor for the resolution criterion */ IONIC.api.imagearchive.ImageArchiveSearchPanel.ED_RESOLUTION = "res"; /** * The name of the editor for the quality criterion */ IONIC.api.imagearchive.ImageArchiveSearchPanel.ED_QUALITY = "qual"; /** * The prefix of the editors for the custom queryables criteria * *
* Since custom criteria have a name, the full name of the editor is
* composed as follow:
* IONIC.api.imagearchive.ImageArchiveSearchPanel.ED_CUSTOM + queryable.getName (),
* where "queryable" is of type
* {@link IONIC.imagearchive.ImageArchiveTool.Queryable}.
*
* This actually installs the "regular" (i.e., not the custom * queryables) search criteria editors into the HTML element. *
* * @private */ IONIC.api.imagearchive.ImageArchiveSearchPanel.prototype.buildComponent = function () { var dh = this.getDomHelper (); var tbd = dh.elt ("tbody"); var tbl = dh.elt ("table", tbd); var alias = IONIC.api.imagearchive.ImageArchiveSearchPanel; dh.append (this.getComponent (), tbl); var thisRef = this; // ----------------- // 1) Fixed criteria // 1.1 keywords this.addEditor (alias.ED_KEYWORDS, "Keywords", IONIC.ui.InputEditor.newInstance (dh)); // 1.2 availability var availStor = dh.elt ("select"); availStor.onchange = function () { thisRef.updateVisibleFields (); } var availEditor = new IONIC.ui.SelectEditor (availStor) availEditor.setOptions (["WCS", "WMS", "WMS-WCS", "WFS"], dh, true); this.addEditor (alias.ED_AVAILABILITY, "Availability", availEditor); // 1.3 type var typeStor = dh.elt ("select"); typeStor.onchange = function () { thisRef.updateVisibleFields (); }; dh.mkOpt (typeStor, "Any"); dh.mkOpt (typeStor, "Granule"); dh.mkOpt (typeStor, "Aggregate"); this.addEditor (alias.ED_TYPE, "Type", new IONIC.ui.SelectEditor (typeStor)); // 1.4 bounding box var boxEditor = IONIC.imagearchive.AbstractImageArchivePanel.buildBoundingBoxEditor (dh, this); this.addEditor (alias.ED_BBOX, "Spatial extent", boxEditor); // 1.5 timestamp boundaries var timestampComponent = IONIC.ui.TimestampIntervalEditor.buildComponent (dh); timestampComponent.startCalendar.setYearSelectStartOffset(4); timestampComponent.endCalendar.setYearSelectStartOffset(4); this.addEditor (alias.ED_TIMESTAMP, "Timestamp", new IONIC.ui.TimestampIntervalEditor (timestampComponent)); // 1.6 resolution this.addEditor (alias.ED_RESOLUTION, "Min. image size", IONIC.ui.InputEditor.newInstance (dh)); // 1.7 quality var qualityEditor = new IONIC.ui.SelectEditor (dh.elt ("select")); var qualityOptions = []; for (var i = 100; i >= 0; i -= 10) { qualityOptions.push ("" + i); } qualityEditor.setOptions (qualityOptions, dh); this.addEditor (alias.ED_QUALITY, "Quality", qualityEditor); this.updateVisibleFields (); }; /** * Shows/hides search form fields according to current selected options. * * @private */ IONIC.api.imagearchive.ImageArchiveSearchPanel.prototype.updateVisibleFields = function () { var availableEditor = this.getEditor (IONIC.api.imagearchive.ImageArchiveSearchPanel.ED_AVAILABILITY); var typeEditor = this.getEditor (IONIC.api.imagearchive.ImageArchiveSearchPanel.ED_TYPE); var resolutionEditor = this.getEditor (IONIC.api.imagearchive.ImageArchiveSearchPanel.ED_RESOLUTION); var qualityEditor = this.getEditor (IONIC.api.imagearchive.ImageArchiveSearchPanel.ED_QUALITY); var availableOption = availableEditor.getValue(); var typeOption = typeEditor.getValue(); // Given an editor, returns the HTML* This actually installs the "regular" (i.e., not the custom * queryables) search criteria editors into the HTML element. *
* * @param {IONIC.imagearchive.ImageArchiveTool.Queryable[]} * customQueryables A list of custom queryables. * * @private */ IONIC.api.imagearchive.ImageArchiveSearchPanel.prototype.addCustomQueryables = function (customQueryables) { var dh = this.getDomHelper (); var alias = IONIC.api.imagearchive.ImageArchiveSearchPanel; var self = this; IONIC.misc.forEach (function (queryable) { var editor, ev, stor; switch (queryable.getType ().toLowerCase ()) { case IONIC.imagearchive.ImageArchiveTool.Queryable.TYPE_DATE: editor = IONIC.imagearchive.editors.CustomQueryableDateEditor.newInstance (dh); break; case IONIC.imagearchive.ImageArchiveTool.Queryable.TYPE_INT: editor = IONIC.imagearchive.editors.CustomQueryableIntEditor.newInstance (dh); break; default: ev = queryable.getEnumValues (); if (ev) { editor = IONIC.imagearchive.editors.CustomQueryableSelectEditor.newInstance (dh); editor.setOptions (ev, dh, true); } else { editor = IONIC.imagearchive.editors.CustomQueryableInputEditor.newInstance (dh); } break; } self.addEditor (alias.ED_CUSTOM + queryable.getName (), queryable.getTitle (), editor); }, customQueryables); }; /** * Resets the search panel (clears all editors) */ IONIC.api.imagearchive.ImageArchiveSearchPanel.prototype.reset = function () { IONIC.misc.unimp ("IONIC.api.imagearchive.ImageArchiveSearchPanel", "reset"); }; /** * Get the HTML component * * @return {HTMLDivElement} the HTML component */ IONIC.api.imagearchive.ImageArchiveSearchPanel.prototype.getComponent = function () { return this._cpnt; }; /** * Will call * {@link IONIC.imagearchive.AbstractImageArchivePanel#setAssociatedMap}, * and then will register itself as a listener to that map, so that it * captures it's current extent in order to use it when querying the * server. * * @param {IONIC.api.maps.Map} map The map to be associated to this * instance. * @see IONIC.imagearchive.AbstractImageArchivePanel#setAssociatedMap */ IONIC.api.imagearchive.ImageArchiveSearchPanel.prototype.setAssociatedMap = function (map) { IONIC.imagearchive.AbstractImageArchivePanel.prototype.setAssociatedMap.call (this, map); var self = this; map.onSelectedBoxChanged.subscribe (function (type, args) { var box = args [0]; if (box) { self.getEditor (IONIC.api.imagearchive.ImageArchiveSearchPanel.ED_BBOX).setValue (box); } }); }; /** * Perform the query * ** See the description of the parameters in the * {@link IONIC.imagearchive.ImageArchiveTool#executeSearch} * function. *
* * @see IONIC.imagearchive.ImageArchiveTool#executeSearch * @see #performSearchWithHandler */ IONIC.api.imagearchive.ImageArchiveSearchPanel.prototype.performSearch = function (beginCallback, iterationCallback, endCallback) { var alias = IONIC.api.imagearchive.ImageArchiveSearchPanel; // Collect parameters... var keywords = this.getEditor (alias.ED_KEYWORDS).getValue (); var resultsType = this.getEditor (alias.ED_TYPE).getValue (); var resultsAvailability = this.getEditor (alias.ED_AVAILABILITY).getValue (); var spatialBounds = this.getEditor (alias.ED_BBOX).getValue (); var temporalBounds = this.getEditor (alias.ED_TIMESTAMP).getValue (); var minimumQuality = this.getEditor (alias.ED_QUALITY).getValue (); var minimumResolution = this.getEditor (alias.ED_RESOLUTION).getValue (); var customQueryables = []; var self = this; this.forEachEditor (function (ed, registeredName) { var val, op, type, name; if (registeredName.indexOf (alias.ED_CUSTOM) >= 0) { name = registeredName.substring (alias.ED_CUSTOM.length); val = ed.getValue (); // we know the editor is of type // IONIC.imagearchive.editors.* op = ed.getOperator (); if (val) { self.withImageArchiveCustomQueryable (name, function (queryable) { var type = queryable.getType (); customQueryables.push ({ name : name, operator : op, value : val, type : type}); }); } } }); var resultsCount = -1; if (resultsAvailability !== "WFS") { if (this.validateSearchForm(keywords, resultsType, resultsAvailability, resultsCount, spatialBounds, temporalBounds, minimumQuality, minimumResolution, customQueryables, this.getPreferredEpsgId ())) { this.getImageArchiveTool ().executeSearch ( keywords, resultsType, resultsAvailability, resultsCount, spatialBounds, temporalBounds, minimumQuality, minimumResolution, customQueryables, this.getPreferredEpsgId (), beginCallback, iterationCallback, endCallback); } else { // Simulate the behaviour of executeSearch beginCallback (false, {}, "{}"); endCallback (false, {}, "{}"); } } else { if (this.validateSearchFormWfs(keywords, resultsCount, spatialBounds, temporalBounds, this.getPreferredEpsgId ())) { this.getImageArchiveTool ().executeWfsSearch ( keywords, resultsCount, spatialBounds, temporalBounds, this.getPreferredEpsgId (), beginCallback, iterationCallback, endCallback); } else { // Simulate the behaviour of executeSearch beginCallback (false, {}, "{}"); endCallback (false, {}, "{}"); } } }; /** * @ignore */ IONIC.api.imagearchive.ImageArchiveSearchPanel.prototype.validateSearchFormWfs = function(keywords, resultsCount, spatialBounds, temporalBounds, srs) { return this.validateSearchFormCommon (keywords, resultsCount, spatialBounds, temporalBounds); }; /** * @ignore */ IONIC.api.imagearchive.ImageArchiveSearchPanel.prototype.validateSearchForm = function(keywords, resultsType, resultsAvailability, resultsCount, spatialBounds, temporalBounds, minimumQuality, minimumResolution, customQueryables, epsgId) { return this.validateSearchFormCommon (keywords, resultsCount, spatialBounds, temporalBounds); }; /** * @ignore */ IONIC.api.imagearchive.ImageArchiveSearchPanel.prototype.validateSearchFormCommon = function(keywords, resultsCount, spatialBounds, temporalBounds) { function display (msg) { alert("One search field is invalid: " + msg); return false; } if ((!temporalBounds[0] && temporalBounds[1]) || (temporalBounds[0] && !temporalBounds[1])) display ("Wrong temporal bounds. Please input exactly 0 or 2 values."); else if (spatialBounds === null) display ("Invalid spatial extent."); else if (Date.parse(temporalBounds[0]) > Date.parse(temporalBounds[1])) display ("First date must be before second date."); else return true; }; /** * Perform the query, but with a dedicated results handler. * * @param {IONIC.misc.AbstractResultsHandler} handler A * results handler that will be in charge of handling the results. */ IONIC.api.imagearchive.ImageArchiveSearchPanel.prototype.performSearchWithHandler = function (handler) { handler.onB4RequestSubmitted (); // Search this.performSearch ( function (success, obj, rt, req) { handler.onBegin (success, obj, rt, req); }, function (node, parent, pos, cnt, depth, req) { handler.onIterate (node, parent, pos, cnt, depth, req); }, function (success, obj, req) { handler.onEnd (success, obj, req); }); }; /** * Get the custom queryables. * ** WARNING: You should only use this when you are sure * they have already been discovered. *
* * @return {IONIC.imagearchive.ImageArchiveTool.Queryable[]} an * array of custom queryables, or undefined * @private */ IONIC.api.imagearchive.ImageArchiveSearchPanel.prototype.getImageArchiveCustomQueryables = function () { return this._cq; }; /** * Set the custom queryables. * * @param {IONIC.imagearchive.ImageArchiveTool.Queryable[]} custQuer * An array of custom queryables * @private */ IONIC.api.imagearchive.ImageArchiveSearchPanel.prototype.setImageArchiveCustomQueryables = function (custQuer) { this._cq = custQuer; }; /** * @param {function} callback A function of one argument: An array of * custom queryables * @private */ IONIC.api.imagearchive.ImageArchiveSearchPanel.prototype.withImageArchiveCustomQueryables = function (callback) { var self; if (! this.getImageArchiveCustomQueryables ()) { self = this; this.getImageArchiveTool ().withServerStatus (function (statusObj) { self.setImageArchiveCustomQueryables (statusObj.customQueryables); if (callback) { callback (statusObj.customQueryables); } }); } else { if (callback) { callback (this.getImageArchiveCustomQueryables ()); } } }; /** * @param {string} name The name of the custom queryable * @param {function} callback A function of one argument: the type * @private */ IONIC.api.imagearchive.ImageArchiveSearchPanel.prototype.withImageArchiveCustomQueryable = function (name, callback) { this.withImageArchiveCustomQueryables (function (cq) { var found; var alias = IONIC.api.imagearchive.ImageArchiveSearchPanel; IONIC.misc.forEach (function (quer) { if (quer.getName () === name) { found = quer; } }, cq); if (callback) { callback (found); } }); }; /* * Copyright 2005- by IONIC Software S.A., * 18 Av Wallonie, 4460 Grace-Hollogne, Belgium. * All rights reserved. * * This software is the confidential and proprietary information * of IONIC Software S.A.("Confidential Information"). * You shall not disclose such Confidential Information and shall use * it only in accordance with the terms of the license agreement * you entered into with IONIC Software. */ /** * @constructor * * @class * * A {@link IONIC.api.imagearchive.ImageArchiveBrowsePanel} holds two * trees: One of which represents the directory structure of the * ImageArchive server, and the other represents what's inside the * current directory level * * @extends IONIC.imagearchive.AbstractImageArchivePanel * * @param {HTMLElement} treeElt The containing aggregate tree HTML element, or its * ID. * * @param {HTMLElement} resElt The containing results HTML element, or its * ID. * * @param {IONIC.api.imagearchive.ServerRef} serverRef A reference to * the image archive server * * @param {HTMLWindow} win (Optional) The window in which is the * document holding the element named "htmlElt", if "htmlElt" is * a string (defaults to the current window). */ IONIC.api.imagearchive.ImageArchiveBrowsePanel = function (treeElt, resElt, serverRef, win, timeline) { IONIC.imagearchive.AbstractImageArchivePanel.call (this, treeElt, serverRef, win); var dh = this.getDomHelper (); treeElt = dh.get(treeElt); resElt = dh.get(resElt); YAHOO.util.Dom.addClass (treeElt, "aggregateTree"); YAHOO.util.Dom.addClass (resElt, "granulesTree"); this._aggregateDecorator = null; this._granuleDecorator = null; this._tree = new YAHOO.widget.TreeView (treeElt); this._resultsListElt = resElt; this._timeline = timeline; // Set the loader for the nodes var self = this; this._tree.setDynamicLoad (function (node, callback) { self.loadChildren (node, callback); }, 1); // Build the directory tree's top node var root = this._tree.getRoot (); var data = IONIC.api.imagearchive.ImageArchiveBrowsePanel.makeNodeDataForDirectoryNode ( this, {name : "ROOT"}); var unused = new YAHOO.widget.TextNode (data, root, false); this.initHolderWithIAData(unused, data); this._tree.subscribe("labelClick", function(node) { self.loadResultsForNodeObject (node, true); }); this._tree.draw (); }; IONIC.misc.extendType (IONIC.api.imagearchive.ImageArchiveBrowsePanel, IONIC.imagearchive.AbstractImageArchivePanel); /** * Fills the granule list (the list on the right of the aggregate tree). * * @param {object} objectNode The YAHOO TextNode containing the IA object * @private */ IONIC.api.imagearchive.ImageArchiveBrowsePanel.prototype.loadResultsForNodeObject = function (objectNode, clearTimeline) { var self = this; this.clearResultsList (); var callback = function (iaObject) { var childrenInfos = iaObject.getChildrenInfos (); var resultsList = self.getResultsListElt (); var dh = self.getDomHelper (); var htmlElements = []; self.clearResultsList (); if (self._timeline && clearTimeline) self._timeline.clear(); if (childrenInfos) { IONIC.misc.forEach (function (child) { var data, href, textNode; var typeI = IONIC.api.imagearchive.IAObject.typeStringToType(child.type); // Granule -> Display to the right tree var childIAObject = IONIC.api.imagearchive.IAObject.fromTransportFormat(iaObject.getServerRef(), child); if (typeI === IONIC.api.imagearchive.IAObject.TYPE_GRANULE && (child.availabilityWMS || child.availabilityWCS)) { var elt = dh.elt ("a"); elt.href = "#"; // Display details when elt.onclick = function () { SearchModule.getDetailPanel ().renderDetailsByName (child.name); }; elt.iaObjectName = child.name; // TODO check if this is still necessary dh.append (elt, dh.txt (child.name)); dh.append (resultsList, elt, dh.elt ("br")); self.initHolderWithIAObject(elt, childIAObject, false); child.objectHolder = elt; self.addPopup (elt, elt); htmlElements.push (elt); if (self._timeline) self._timeline.addIAObject(elt); } else if (child.objectHolder && self._timeline) { self._timeline.addIAObject(child.objectHolder); } }, childrenInfos); if (self._timeline) self._timeline.recenter(); if (htmlElements.length > 0 && self._granuleDecorator) { self._granuleDecorator.addElements (htmlElements); } } if (self._timeline) self._timeline.repaintObjects(); }; objectNode.getIAObject(callback, true); }; /** * Get the directory tree * * @return {YAHOO.widget.TreeView} the directory tree */ IONIC.api.imagearchive.ImageArchiveBrowsePanel.prototype.getDirectoryTree = function () { return this._tree; }; /** * Get the results (flat) tree * * @return {YAHOO.widget.TreeView} the results flat tree */ IONIC.api.imagearchive.ImageArchiveBrowsePanel.prototype.getResultsListElt = function () { return this._resultsListElt; }; /** * Delete all the nodes of the results tree * @private */ IONIC.api.imagearchive.ImageArchiveBrowsePanel.prototype.clearResultsList = function () { if (this._granuleDecorator) { this._granuleDecorator.deleteElements (null); } var dh = this.getDomHelper (); var self = this; var resultsDiv = this.getResultsListElt (); IONIC.misc.forEach (function (elt) { self.deletePopup (elt); }, resultsDiv.getElementsByTagName("a")); this.getDomHelper ().clr (resultsDiv); }; /** * An additional 'onhover' event timeout that slows the creation of popups down. * @ignore */ IONIC.api.imagearchive.ImageArchiveBrowsePanel.POPUPTIMEOUT = 500; IONIC.api.imagearchive.ImageArchiveBrowsePanel.prototype.initHolderWithIAData = function (holder, data) { if (holder) { holder.data = data var self = this; holder.getPopup = function () { if (holder.popupElt) { return holder.popupElt; } else { holder.popupElt = new IONIC.api.imagearchive.IAObjectPopup (self.getDomHelper (), null, self.getAssociatedMap ()); holder.isPopupHidden = true; return holder.popupElt; } } holder.createMoveOverHandler = function () { var mouseoverHandler = function (evt) { holder.getIAObject(function (iaObj) { if (!holder.isPopupHidden) { holder.getPopup ().setContent(iaObj); holder.getPopup ().show(); } }, true); }; return function (evt) { holder.isPopupHidden = false; setTimeout (function () { if (!holder.isPopupHidden) { mouseoverHandler (evt); } }, IONIC.api.imagearchive.ImageArchiveBrowsePanel.POPUPTIMEOUT); } }; holder.createMoveOutHandler = function () { return function (evt) { holder.getPopup().hide(); holder.isPopupHidden = true; }; }; holder.removePopup = function () { if (holder.popupElt) { holder.popupElt.destroy (); holder.popupElt = null; } } /** * Caching/LazyLoading method for the IAObject. * This method relies on a holder object, that must initially at least contain a 'data' attribute * with the uuid and/or the object name. * After the first call to this method, the holder object will contain a 'iaObject' attribute * that contains the actual IAObject. Reciprocally, the holder object will contein a 'iaObject' * attribute to the IA object. * @param {object} node the object that holds or will hold the iaObject, as a 'iaObject' attribute * @param {function} callback the callback to execute once the object is retrieved * @param {boolean} full whether to retrieve the full object description or not * @private */ holder.getIAObject = function (callback, full) { var cbArray = this.waitingCallbacks; if (!cbArray) cbArray = this.waitingCallbacks = new Array(); if (this.isLoadingIAObject) { cbArray[cbArray.length] = callback; return; } else if (this.displayedObject && (!full || this.displayedObject.isFull)) { callback(this.displayedObject); } else { cbArray[cbArray.length] = callback; this.isLoadingIAObject = true; var withObjectFunc; // if the UUID is available, use it fore more efficiency if (this.data.uuid) withObjectFunc = self.getImageArchiveTool().withObjectById; else withObjectFunc = self.getImageArchiveTool().withObjectByName; var holderObj = this; withObjectFunc.call (self.getImageArchiveTool(), this.data.uuid || this.data.iasObjectName, self.getPreferredEpsgId (), function(iaObject) { //self.initHolderWithIAObject(holderObj, iaObject, full); holderObj.displayedObject = iaObject; holderObj.displayedObject.isFull = full; holderObj.isLoadingIAObject = false; for (var idx in holderObj.waitingCallbacks) { holderObj.waitingCallbacks[idx](iaObject); } holderObj.waitingCallbacks = new Array(); }, full); } } } } IONIC.api.imagearchive.ImageArchiveBrowsePanel.prototype.initHolderWithIAObject = function (holder, iaObject, full) { if (holder && iaObject) { holder.displayedObject = iaObject; holder.displayedObject.isFull = full; this.initHolderWithIAData(holder, { uuid:iaObject.getId(), iasObjectName:iaObject.getName(), title:iaObject.getId()}); } } /** * Function that will be called when a node of the tree * has to be expanded. * * @param {IONIC.api.imagearchive.ImageArchiveBrowsePanel} browsePanel * An instance of browse panel * @param {YAHOO.widget.Node} node The current node of the tree that * must be expanded * @param {function} callback A function of 0 arguments to be called * when the loading is done */ IONIC.api.imagearchive.ImageArchiveBrowsePanel.prototype.loadChildren = function (node, callback) { var self = this; var iasTool = new IONIC.imagearchive.ImageArchiveTool (); node.getIAObject( function (iaObject) { // Create new nodes var childrenInfos = iaObject.getChildrenInfos (); var textNodes = []; var displayGranuleTree = false; if (childrenInfos) { IONIC.misc.forEach (function (child) { var data, href, textNode; if (IONIC.api.imagearchive.IAObject.typeStringToType (child.type) === IONIC.api.imagearchive.IAObject.TYPE_AGGREGATE) { data = { label: child.name, iasObjectName : child.name, uuid : child.uuid}; textNode = new YAHOO.widget.TextNode (data, node, false); self.initHolderWithIAData(textNode, data); child.objectHolder = textNode; textNodes.push (textNode); } else { // Children are granule, so we display granule list displayGranuleTree = true; } }, childrenInfos); if (displayGranuleTree) { self.loadResultsForNodeObject (node); } if (callback) { callback (); var htmlElements = []; IONIC.misc.forEach (function (n) { self.addPopup (n.getLabelEl (), n); n.getLabelEl ().iaObjectName = n.data.iasObjectName; // TODO check if this is still necessary htmlElements.push (n.getLabelEl ()); }, textNodes); // Add contextual menu if (htmlElements.length > 0 && self._aggregateDecorator) { self._aggregateDecorator.addElements (htmlElements); } } } }, true); }; /** * @param {object} child An object with at least the * properties:name
* @private
*/
IONIC.api.imagearchive.ImageArchiveBrowsePanel.makeNodeDataForDirectoryNode = function (browsePanel, child) {
return {label : child.name,
iasObjectName : child.name,
uuid : child.uuid};
};
/**
* Sets an HTML decorator for the aggregate tree elements.
* @param {Object} decorator The decorator.
* @see {IONIC.api.imagearchive.DefaultTableRowRenderer.setHtmlDecorator}
*/
IONIC.api.imagearchive.ImageArchiveBrowsePanel.prototype.setAggregateHtmlDecorator = function (decorator) {
this._aggregateDecorator = decorator;
if (this._timeline) {
this._timeline.aggregateDecorator = decorator;
}
};
/**
* Sets an HTML decorator for the granule elements.
* @param {Object} decorator The decorator.
* @see {IONIC.api.imagearchive.DefaultTableRowRenderer.setHtmlDecorator}
*/
IONIC.api.imagearchive.ImageArchiveBrowsePanel.prototype.setGranuleHtmlDecorator = function (decorator) {
this._granuleDecorator = decorator;
if (this._timeline) {
this._timeline.granuleDecorator = decorator;
}
};
/**
* Asynchronous: gets the iaobject, then set the mouse handlers.
* @param {HTMLElement} node The element which will be associated with the popup (will trigger the onmouseover events).
* @param {object} objectHolderNode The object that holds the reference to the iaObject.
* @private
*/
IONIC.api.imagearchive.ImageArchiveBrowsePanel.prototype.addPopup = function (node, objectHolderNode) {
var self = this;
node.onmouseover = objectHolderNode.createMoveOverHandler();
node.onmouseout = objectHolderNode.createMoveOutHandler();
node.displayedObjectHolder = objectHolderNode;
//node.popupElt = popupElt;
};
/**
* Deletes the popup associated with an element.
* @param {HtmlElement} elt The element which will be associated with the popup (will trigger the onmouseover events).
* @private
*/
IONIC.api.imagearchive.ImageArchiveBrowsePanel.prototype.deletePopup = function (elt) {
elt.onmouseover = null;
elt.onmouseout = null;
if (elt.displayedObjectHolder) {
elt.displayedObjectHolder.removePopup();
}
};
/**
* @constructor
*
* @class
*
* A {@link IONIC.api.imagearchive.ImageArchiveDetailPanel} holds a table
* representing details about an {@link IONIC.api.imagearchive.IAObject}.
*
* @extends IONIC.imagearchive.AbstractImageArchivePanel
*
* *
* To an instance of this type, can be attached a * {@link IONIC.api.maps.Map}. If this is the case, the map will be * used for two things: *
*