mirror of
https://github.com/cds-astro/aladin-lite.git
synced 2025-12-12 15:49:18 -08:00
doc: add Image methods
This commit is contained in:
@@ -147,6 +147,9 @@ export class PolySelect extends FSM {
|
||||
let finish = () => {
|
||||
if (this.coos.length <= 2) {
|
||||
console.warn("Invalid selection, please draw at least a 3 vertices polygon")
|
||||
|
||||
view.mustClearCatalog = true;
|
||||
view.requestRedraw();
|
||||
this.dispatch("off")
|
||||
return;
|
||||
}
|
||||
|
||||
687
src/js/HiPS.js
687
src/js/HiPS.js
@@ -445,7 +445,368 @@ export let HiPS = (function () {
|
||||
self._saveInCache();
|
||||
}
|
||||
|
||||
HiPS.prototype.setView = function (view) {
|
||||
/**
|
||||
* Checks if the HiPS represents a planetary body.
|
||||
*
|
||||
* This method returns a boolean indicating whether the HiPS corresponds to a planetary body, e.g. the earth or a celestial body.
|
||||
*
|
||||
* @memberof HiPS
|
||||
*
|
||||
* @returns {boolean} Returns true if the HiPS represents a planetary body; otherwise, returns false.
|
||||
*/
|
||||
HiPS.prototype.isPlanetaryBody = function () {
|
||||
return this.hipsBody !== undefined;
|
||||
};
|
||||
|
||||
/**
|
||||
* Sets the image format for the HiPS.
|
||||
*
|
||||
* This method updates the image format of the HiPS, performs format validation, and triggers the update of metadata.
|
||||
*
|
||||
* @memberof HiPS
|
||||
*
|
||||
* @param {string} format - The desired image format. Should be one of ["fits", "png", "jpg", "webp"].
|
||||
*
|
||||
* @throws {string} Throws an error if the provided format is not one of the supported formats or if the format is not available for the specific HiPS.
|
||||
*/
|
||||
HiPS.prototype.setImageFormat = function (format) {
|
||||
let self = this;
|
||||
self.query.then(() => {
|
||||
let imgFormat = format.toLowerCase();
|
||||
|
||||
if (
|
||||
imgFormat !== "fits" &&
|
||||
imgFormat !== "png" &&
|
||||
imgFormat !== "jpg" &&
|
||||
imgFormat !== "jpeg" &&
|
||||
imgFormat !== "webp"
|
||||
) {
|
||||
throw 'Formats must lie in ["fits", "png", "jpg", "webp"]';
|
||||
}
|
||||
|
||||
if (imgFormat === "jpg") {
|
||||
imgFormat = "jpeg";
|
||||
}
|
||||
|
||||
// Passed the check, we erase the image format with the new one
|
||||
// We do nothing if the imgFormat is the same
|
||||
if (self.imgFormat === imgFormat) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Check the properties to see if the given format is available among the list
|
||||
// If the properties have not been retrieved yet, it will be tested afterwards
|
||||
const availableFormats = self.formats;
|
||||
// user wants a fits but the metadata tells this format is not available
|
||||
if (
|
||||
imgFormat === "fits" &&
|
||||
availableFormats.indexOf("fits") < 0
|
||||
) {
|
||||
throw self.id + " does not provide fits tiles";
|
||||
}
|
||||
|
||||
if (
|
||||
imgFormat === "webp" &&
|
||||
availableFormats.indexOf("webp") < 0
|
||||
) {
|
||||
throw self.id + " does not provide webp tiles";
|
||||
}
|
||||
|
||||
if (
|
||||
imgFormat === "png" &&
|
||||
availableFormats.indexOf("png") < 0
|
||||
) {
|
||||
throw self.id + " does not provide png tiles";
|
||||
}
|
||||
|
||||
if (
|
||||
imgFormat === "jpeg" &&
|
||||
availableFormats.indexOf("jpeg") < 0
|
||||
) {
|
||||
throw self.id + " does not provide jpeg tiles";
|
||||
}
|
||||
|
||||
// Switch from png/webp/jpeg to fits
|
||||
if (
|
||||
(self.imgFormat === "png" ||
|
||||
self.imgFormat === "webp" ||
|
||||
self.imgFormat === "jpeg") &&
|
||||
imgFormat === "fits"
|
||||
) {
|
||||
if (Number.isFinite(self.defaultFitsMinCut) && Number.isFinite(self.defaultFitsMaxCut)) {
|
||||
// reset cuts to those given from the properties
|
||||
self.setCuts(self.defaultFitsMinCut, self.defaultFitsMaxCut);
|
||||
}
|
||||
// Switch from fits to png/webp/jpeg
|
||||
} else if (self.imgFormat === "fits") {
|
||||
self.setCuts(0.0, 1.0);
|
||||
}
|
||||
|
||||
// Check if it is a fits
|
||||
self.imgFormat = imgFormat;
|
||||
|
||||
self._updateMetadata();
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Sets the opacity factor when rendering the HiPS
|
||||
*
|
||||
* @memberof HiPS
|
||||
*
|
||||
* @returns {string[]} Returns the formats accepted for the survey, i.e. the formats of tiles that are availables. Could be PNG, WEBP, JPG and FITS.
|
||||
*/
|
||||
HiPS.prototype.getAvailableFormats = function () {
|
||||
return this.formats;
|
||||
};
|
||||
|
||||
/**
|
||||
* Sets the opacity factor when rendering the HiPS
|
||||
*
|
||||
* @memberof HiPS
|
||||
*
|
||||
* @param {number} opacity - Opacity of the survey to set. Between 0 and 1
|
||||
*/
|
||||
HiPS.prototype.setOpacity = function (opacity) {
|
||||
this.setOptions({opacity})
|
||||
};
|
||||
|
||||
/**
|
||||
* Sets the blending mode when rendering the HiPS
|
||||
*
|
||||
* @memberof HiPS
|
||||
*
|
||||
* @param {boolean} [additive=false] - When rendering this survey on top of the already rendered ones, the final color of the screen is computed like:
|
||||
* <br />
|
||||
* <br />opacity * this_survey_color + (1 - opacity) * already_rendered_color for the default mode
|
||||
* <br />opacity * this_survey_color + already_rendered_color for the additive mode
|
||||
* <br />
|
||||
* <br />
|
||||
* Additive mode allows you to do linear survey color combination i.e. let's define 3 surveys named s1, s2, s3. Each could be associated to one color channel, i.e. s1 with red, s2 with green and s3 with the blue color channel.
|
||||
* If the additive blending mode is enabled, then the final pixel color of your screen will be: rgb = [s1_opacity * s1_color; s2_opacity * s2_color; s3_opacity * s3_color]
|
||||
*/
|
||||
HiPS.prototype.setBlendingConfig = function (additive = false) {
|
||||
this.setOptions({additive});
|
||||
};
|
||||
|
||||
/**
|
||||
* Sets the colormap when rendering the HiPS.
|
||||
*
|
||||
* @memberof HiPS
|
||||
*
|
||||
* @param {string} [colormap="grayscale"] - The colormap label to use. See {@link https://matplotlib.org/stable/users/explain/colors/colormaps.html|here} for more info about colormaps.
|
||||
* Possible values are:
|
||||
* <br>"blues"
|
||||
* <br>"cividis"
|
||||
* <br>"cubehelix"
|
||||
* <br>"eosb"
|
||||
* <br>"grayscale"
|
||||
* <br>"inferno"
|
||||
* <br>"magma"
|
||||
* <br>"native"
|
||||
* <br>"parula"
|
||||
* <br>"plasma"
|
||||
* <br>"rainbow"
|
||||
* <br>"rdbu"
|
||||
* <br>"rdylbu"
|
||||
* <br>"redtemperature"
|
||||
* <br>"sinebow"
|
||||
* <br>"spectral"
|
||||
* <br>"summer"
|
||||
* <br>"viridis"
|
||||
* <br>"ylgnbu"
|
||||
* <br>"ylorbr"
|
||||
* <br>"red"
|
||||
* <br>"green"
|
||||
* <br>"blue"
|
||||
* @param {Object} [options] - Options for the colormap
|
||||
* @param {string} [options.stretch] - Stretching function of the colormap. Possible values are 'linear', 'asinh', 'log', 'sqrt', 'pow'. If no given, will not change it.
|
||||
* @param {boolean} [options.reversed=false] - Reverse the colormap axis.
|
||||
*/
|
||||
HiPS.prototype.setColormap = function (colormap, options) {
|
||||
this.setOptions({colormap, ...options})
|
||||
};
|
||||
|
||||
/**
|
||||
* Sets the gamma correction factor for the HiPS.
|
||||
*
|
||||
* This method updates the gamma of the HiPS.
|
||||
*
|
||||
* @memberof HiPS
|
||||
*
|
||||
* @param {number} minCut - The low cut value to set for the HiPS.
|
||||
* @param {number} maxCut - The high cut value to set for the HiPS.
|
||||
*/
|
||||
HiPS.prototype.setCuts = function (minCut, maxCut) {
|
||||
this.setOptions({minCut, maxCut})
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns the low and high cuts under the form of a 2 element array
|
||||
*
|
||||
* @memberof HiPS
|
||||
*
|
||||
* @returns {number[]} The low and high cut values for the HiPS.
|
||||
*/
|
||||
HiPS.prototype.getCuts = function () {
|
||||
return this.colorCfg.getCuts();
|
||||
};
|
||||
|
||||
/**
|
||||
* Sets the gamma correction factor for the HiPS.
|
||||
*
|
||||
* This method updates the gamma of the HiPS.
|
||||
*
|
||||
* @memberof HiPS
|
||||
*
|
||||
* @param {number} gamma - The saturation value to set for the HiPS. Between 0.1 and 10
|
||||
*/
|
||||
HiPS.prototype.setGamma = function (gamma) {
|
||||
this.setOptions({gamma})
|
||||
};
|
||||
|
||||
/**
|
||||
* Sets the saturation for the HiPS.
|
||||
*
|
||||
* This method updates the saturation of the HiPS.
|
||||
*
|
||||
* @memberof HiPS
|
||||
*
|
||||
* @param {number} saturation - The saturation value to set for the HiPS. Between 0 and 1
|
||||
*/
|
||||
HiPS.prototype.setSaturation = function (saturation) {
|
||||
this.setOptions({saturation})
|
||||
};
|
||||
|
||||
/**
|
||||
* Sets the brightness for the HiPS.
|
||||
*
|
||||
* This method updates the brightness of the HiPS.
|
||||
*
|
||||
* @memberof HiPS
|
||||
*
|
||||
* @param {number} brightness - The brightness value to set for the HiPS. Between 0 and 1
|
||||
*/
|
||||
HiPS.prototype.setBrightness = function (brightness) {
|
||||
this.setOptions({brightness})
|
||||
};
|
||||
|
||||
/**
|
||||
* Sets the contrast for the HiPS.
|
||||
*
|
||||
* This method updates the contrast of the HiPS and triggers the update of metadata.
|
||||
*
|
||||
* @memberof HiPS
|
||||
*
|
||||
* @param {number} contrast - The contrast value to set for the HiPS. Between 0 and 1
|
||||
*/
|
||||
HiPS.prototype.setContrast = function (contrast) {
|
||||
this.setOptions({contrast})
|
||||
};
|
||||
|
||||
// Private method for updating the backend with the new meta
|
||||
HiPS.prototype._updateMetadata = function () {
|
||||
try {
|
||||
if (this.added) {
|
||||
this.view.wasm.setImageMetadata(this.layer, {
|
||||
...this.colorCfg.get(),
|
||||
longitudeReversed: this.longitudeReversed,
|
||||
imgFormat: this.imgFormat,
|
||||
});
|
||||
// once the meta have been well parsed, we can set the meta
|
||||
ALEvent.HIPS_LAYER_CHANGED.dispatchedTo(this.view.aladinDiv, {
|
||||
layer: this,
|
||||
});
|
||||
|
||||
// Save it in the JS HiPS cache
|
||||
this._saveInCache();
|
||||
}
|
||||
} catch (e) {
|
||||
// Display the error message
|
||||
console.error(e);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Set color options generic method for changing colormap, opacity, ... of the HiPS
|
||||
*
|
||||
* @memberof HiPS
|
||||
*
|
||||
* @param {Object} options
|
||||
* @param {number} [options.opacity=1.0] - Opacity of the survey or image (value between 0 and 1).
|
||||
* @param {string} [options.colormap="native"] - The colormap configuration for the survey or image.
|
||||
* @param {string} [options.stretch="linear"] - The stretch configuration for the survey or image.
|
||||
* @param {boolean} [options.reversed=false] - If true, the colormap is reversed; otherwise, it is not reversed.
|
||||
* @param {number} [options.minCut] - The minimum cut value for the color configuration. If not given, 0.0 for JPEG/PNG surveys, the value of the property file for FITS surveys
|
||||
* @param {number} [options.maxCut] - The maximum cut value for the color configuration. If not given, 1.0 for JPEG/PNG surveys, the value of the property file for FITS surveys
|
||||
* @param {boolean} [options.additive=false] - If true, additive blending is applied; otherwise, it is not applied.
|
||||
* @param {number} [options.gamma=1.0] - The gamma correction value for the color configuration.
|
||||
* @param {number} [options.saturation=0.0] - The saturation value for the color configuration.
|
||||
* @param {number} [options.brightness=0.0] - The brightness value for the color configuration.
|
||||
* @param {number} [options.contrast=0.0] - The contrast value for the color configuration.
|
||||
*/
|
||||
HiPS.prototype.setOptions = function(options) {
|
||||
this.colorCfg.setOptions(options);
|
||||
this.options = {...this.options, ...options};
|
||||
|
||||
this._updateMetadata();
|
||||
};
|
||||
|
||||
/**
|
||||
* Toggle the HiPS turning its opacity to 0 back and forth
|
||||
*
|
||||
* @memberof HiPS
|
||||
*/
|
||||
HiPS.prototype.toggle = function () {
|
||||
const opacity = this.getOpacity()
|
||||
if (opacity != 0.0) {
|
||||
this.prevOpacity = opacity;
|
||||
this.setOpacity(0.0);
|
||||
} else {
|
||||
this.setOpacity(this.prevOpacity);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Old method for setting the opacity use {@link HiPS#setOpacity} instead
|
||||
*
|
||||
* @memberof HiPS
|
||||
* @deprecated
|
||||
*/
|
||||
HiPS.prototype.setAlpha = HiPS.prototype.setOpacity;
|
||||
|
||||
// @api
|
||||
HiPS.prototype.getColorCfg = function () {
|
||||
return this.colorCfg;
|
||||
};
|
||||
|
||||
/**
|
||||
* Get the opacity of the HiPS layer
|
||||
*
|
||||
* @memberof HiPS
|
||||
*
|
||||
* @returns {number} The opacity of the layer
|
||||
*/
|
||||
HiPS.prototype.getOpacity = function () {
|
||||
return this.colorCfg.getOpacity();
|
||||
};
|
||||
|
||||
HiPS.prototype.getAlpha = HiPS.prototype.getOpacity;
|
||||
|
||||
/**
|
||||
* Read a specific screen pixel value
|
||||
*
|
||||
* @todo This has not yet been implemented
|
||||
* @memberof HiPS
|
||||
* @param {number} x - x axis in screen pixels to probe
|
||||
* @param {number} y - y axis in screen pixels to probe
|
||||
* @returns {number} the value of that pixel
|
||||
*/
|
||||
HiPS.prototype.readPixel = function (x, y) {
|
||||
return this.view.wasm.readPixel(x, y, this.layer);
|
||||
};
|
||||
|
||||
HiPS.prototype._setView = function (view) {
|
||||
let self = this;
|
||||
|
||||
// do not allow to call setView multiple times otherwise
|
||||
@@ -580,292 +941,7 @@ export let HiPS = (function () {
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Checks if the HiPS represents a planetary body.
|
||||
*
|
||||
* This method returns a boolean indicating whether the HiPS corresponds to a planetary body, e.g. the earth or a celestial body.
|
||||
*
|
||||
* @memberof HiPS
|
||||
*
|
||||
* @returns {boolean} Returns true if the HiPS represents a planetary body; otherwise, returns false.
|
||||
*/
|
||||
HiPS.prototype.isPlanetaryBody = function () {
|
||||
return this.hipsBody !== undefined;
|
||||
};
|
||||
|
||||
/**
|
||||
* Sets the image format for the HiPS.
|
||||
*
|
||||
* This method updates the image format of the HiPS, performs format validation, and triggers the update of metadata.
|
||||
*
|
||||
* @memberof HiPS
|
||||
*
|
||||
* @param {string} format - The desired image format. Should be one of ["fits", "png", "jpg", "webp"].
|
||||
*
|
||||
* @throws {string} Throws an error if the provided format is not one of the supported formats or if the format is not available for the specific HiPS.
|
||||
*/
|
||||
HiPS.prototype.setImageFormat = function (format) {
|
||||
let self = this;
|
||||
self.query.then(() => {
|
||||
let imgFormat = format.toLowerCase();
|
||||
|
||||
if (
|
||||
imgFormat !== "fits" &&
|
||||
imgFormat !== "png" &&
|
||||
imgFormat !== "jpg" &&
|
||||
imgFormat !== "jpeg" &&
|
||||
imgFormat !== "webp"
|
||||
) {
|
||||
throw 'Formats must lie in ["fits", "png", "jpg", "webp"]';
|
||||
}
|
||||
|
||||
if (imgFormat === "jpg") {
|
||||
imgFormat = "jpeg";
|
||||
}
|
||||
|
||||
// Passed the check, we erase the image format with the new one
|
||||
// We do nothing if the imgFormat is the same
|
||||
if (self.imgFormat === imgFormat) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Check the properties to see if the given format is available among the list
|
||||
// If the properties have not been retrieved yet, it will be tested afterwards
|
||||
const availableFormats = self.formats;
|
||||
// user wants a fits but the metadata tells this format is not available
|
||||
if (
|
||||
imgFormat === "fits" &&
|
||||
availableFormats.indexOf("fits") < 0
|
||||
) {
|
||||
throw self.id + " does not provide fits tiles";
|
||||
}
|
||||
|
||||
if (
|
||||
imgFormat === "webp" &&
|
||||
availableFormats.indexOf("webp") < 0
|
||||
) {
|
||||
throw self.id + " does not provide webp tiles";
|
||||
}
|
||||
|
||||
if (
|
||||
imgFormat === "png" &&
|
||||
availableFormats.indexOf("png") < 0
|
||||
) {
|
||||
throw self.id + " does not provide png tiles";
|
||||
}
|
||||
|
||||
if (
|
||||
imgFormat === "jpeg" &&
|
||||
availableFormats.indexOf("jpeg") < 0
|
||||
) {
|
||||
throw self.id + " does not provide jpeg tiles";
|
||||
}
|
||||
|
||||
// Switch from png/webp/jpeg to fits
|
||||
if (
|
||||
(self.imgFormat === "png" ||
|
||||
self.imgFormat === "webp" ||
|
||||
self.imgFormat === "jpeg") &&
|
||||
imgFormat === "fits"
|
||||
) {
|
||||
if (Number.isFinite(self.defaultFitsMinCut) && Number.isFinite(self.defaultFitsMaxCut)) {
|
||||
// reset cuts to those given from the properties
|
||||
self.setCuts(self.defaultFitsMinCut, self.defaultFitsMaxCut);
|
||||
}
|
||||
// Switch from fits to png/webp/jpeg
|
||||
} else if (self.imgFormat === "fits") {
|
||||
self.setCuts(0.0, 1.0);
|
||||
}
|
||||
|
||||
// Check if it is a fits
|
||||
self.imgFormat = imgFormat;
|
||||
|
||||
self._updateMetadata();
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Sets the opacity factor when rendering the HiPS
|
||||
*
|
||||
* @memberof HiPS
|
||||
*
|
||||
* @returns {string[]} Returns the formats accepted for the survey, i.e. the formats of tiles that are availables. Could be PNG, WEBP, JPG and FITS.
|
||||
*/
|
||||
HiPS.prototype.getAvailableFormats = function () {
|
||||
return this.formats;
|
||||
};
|
||||
|
||||
/**
|
||||
* Sets the opacity factor when rendering the HiPS
|
||||
*
|
||||
* @memberof HiPS
|
||||
*
|
||||
* @param {number} opacity - Opacity of the survey to set. Between 0 and 1
|
||||
*/
|
||||
HiPS.prototype.setOpacity = function (opacity) {
|
||||
this.setOptions({opacity})
|
||||
};
|
||||
|
||||
/**
|
||||
* Sets the blending mode when rendering the HiPS
|
||||
*
|
||||
* @memberof HiPS
|
||||
*
|
||||
* @param {boolean} [additive=false] -
|
||||
*
|
||||
* @description Two rendering modes are availables i.e. the default one and the additive one.
|
||||
* When rendering this survey on top of the already rendered ones, the final color of the screen is computed like:
|
||||
* <br>
|
||||
* <br>opacity * this_survey_color + (1 - opacity) * already_rendered_color for the default mode
|
||||
* <br>opacity * this_survey_color + already_rendered_color for the additive mode
|
||||
* <br>
|
||||
* <br>
|
||||
* Additive mode allows you to do linear survey color combination i.e. let's define 3 surveys named s1, s2, s3. Each could be associated to one color channel, i.e. s1 with red, s2 with green and s3 with the blue color channel.
|
||||
* If the additive blending mode is enabled, then the final pixel color of your screen will be: rgb = [s1_opacity * s1_color; s2_opacity * s2_color; s3_opacity * s3_color]
|
||||
*/
|
||||
HiPS.prototype.setBlendingConfig = function (additive = false) {
|
||||
this.setOptions({additive});
|
||||
};
|
||||
|
||||
/**
|
||||
* Sets the colormap when rendering the HiPS.
|
||||
*
|
||||
* @memberof HiPS
|
||||
*
|
||||
* @param {string} [colormap="grayscale"] - The colormap label to use. See {@link https://matplotlib.org/stable/users/explain/colors/colormaps.html|here} for more info about colormaps.
|
||||
* Possible values are:
|
||||
* <br>"blues"
|
||||
* <br>"cividis"
|
||||
* <br>"cubehelix"
|
||||
* <br>"eosb"
|
||||
* <br>"grayscale"
|
||||
* <br>"inferno"
|
||||
* <br>"magma"
|
||||
* <br>"native"
|
||||
* <br>"parula"
|
||||
* <br>"plasma"
|
||||
* <br>"rainbow"
|
||||
* <br>"rdbu"
|
||||
* <br>"rdylbu"
|
||||
* <br>"redtemperature"
|
||||
* <br>"sinebow"
|
||||
* <br>"spectral"
|
||||
* <br>"summer"
|
||||
* <br>"viridis"
|
||||
* <br>"ylgnbu"
|
||||
* <br>"ylorbr"
|
||||
* <br>"red"
|
||||
* <br>"green"
|
||||
* <br>"blue"
|
||||
* @param {Object} [options] - Options for the colormap
|
||||
* @param {string} [options.stretch] - Stretching function of the colormap. Possible values are 'linear', 'asinh', 'log', 'sqrt', 'pow'. If no given, will not change it.
|
||||
* @param {boolean} [options.reversed=false] - Reverse the colormap axis.
|
||||
*/
|
||||
HiPS.prototype.setColormap = function (colormap, options) {
|
||||
this.setOptions({colormap, ...options})
|
||||
};
|
||||
|
||||
/**
|
||||
* Sets the gamma correction factor for the HiPS.
|
||||
*
|
||||
* This method updates the gamma of the HiPS.
|
||||
*
|
||||
* @memberof HiPS
|
||||
*
|
||||
* @param {number} minCut - The low cut value to set for the HiPS.
|
||||
* @param {number} maxCut - The high cut value to set for the HiPS.
|
||||
*/
|
||||
HiPS.prototype.setCuts = function (minCut, maxCut) {
|
||||
this.setOptions({minCut, maxCut})
|
||||
};
|
||||
|
||||
HiPS.prototype.getCuts = function () {
|
||||
return this.colorCfg.getCuts();
|
||||
};
|
||||
|
||||
/**
|
||||
* Sets the gamma correction factor for the HiPS.
|
||||
*
|
||||
* This method updates the gamma of the HiPS.
|
||||
*
|
||||
* @memberof HiPS
|
||||
*
|
||||
* @param {number} gamma - The saturation value to set for the HiPS. Between 0.1 and 10
|
||||
*/
|
||||
HiPS.prototype.setGamma = function (gamma) {
|
||||
this.setOptions({gamma})
|
||||
};
|
||||
|
||||
/**
|
||||
* Sets the saturation for the HiPS.
|
||||
*
|
||||
* This method updates the saturation of the HiPS.
|
||||
*
|
||||
* @memberof HiPS
|
||||
*
|
||||
* @param {number} saturation - The saturation value to set for the HiPS. Between 0 and 1
|
||||
*/
|
||||
HiPS.prototype.setSaturation = function (saturation) {
|
||||
this.setOptions({saturation})
|
||||
};
|
||||
|
||||
/**
|
||||
* Sets the brightness for the HiPS.
|
||||
*
|
||||
* This method updates the brightness of the HiPS.
|
||||
*
|
||||
* @memberof HiPS
|
||||
*
|
||||
* @param {number} brightness - The brightness value to set for the HiPS. Between 0 and 1
|
||||
*/
|
||||
HiPS.prototype.setBrightness = function (brightness) {
|
||||
this.setOptions({brightness})
|
||||
};
|
||||
|
||||
/**
|
||||
* Sets the contrast for the HiPS.
|
||||
*
|
||||
* This method updates the contrast of the HiPS and triggers the update of metadata.
|
||||
*
|
||||
* @memberof HiPS
|
||||
*
|
||||
* @param {number} contrast - The contrast value to set for the HiPS. Between 0 and 1
|
||||
*/
|
||||
HiPS.prototype.setContrast = function (contrast) {
|
||||
this.setOptions({contrast})
|
||||
};
|
||||
|
||||
// Private method for updating the backend with the new meta
|
||||
HiPS.prototype._updateMetadata = function () {
|
||||
try {
|
||||
if (this.added) {
|
||||
this.view.wasm.setImageMetadata(this.layer, {
|
||||
...this.colorCfg.get(),
|
||||
longitudeReversed: this.longitudeReversed,
|
||||
imgFormat: this.imgFormat,
|
||||
});
|
||||
// once the meta have been well parsed, we can set the meta
|
||||
ALEvent.HIPS_LAYER_CHANGED.dispatchedTo(this.view.aladinDiv, {
|
||||
layer: this,
|
||||
});
|
||||
|
||||
// Save it in the JS HiPS cache
|
||||
this._saveInCache();
|
||||
}
|
||||
} catch (e) {
|
||||
// Display the error message
|
||||
console.error(e);
|
||||
}
|
||||
};
|
||||
|
||||
HiPS.prototype.setOptions = function(options) {
|
||||
this.colorCfg.setOptions(options);
|
||||
this.options = {...this.options, ...options};
|
||||
|
||||
this._updateMetadata();
|
||||
};
|
||||
|
||||
HiPS.prototype.add = function (layer) {
|
||||
HiPS.prototype._add = function (layer) {
|
||||
this.layer = layer;
|
||||
let self = this;
|
||||
|
||||
@@ -935,43 +1011,6 @@ export let HiPS = (function () {
|
||||
});
|
||||
};
|
||||
|
||||
// @api
|
||||
HiPS.prototype.toggle = function () {
|
||||
const opacity = this.getOpacity()
|
||||
if (opacity != 0.0) {
|
||||
this.prevOpacity = opacity;
|
||||
this.setOpacity(0.0);
|
||||
} else {
|
||||
this.setOpacity(this.prevOpacity);
|
||||
}
|
||||
};
|
||||
|
||||
// @oldapi
|
||||
HiPS.prototype.setAlpha = HiPS.prototype.setOpacity;
|
||||
|
||||
HiPS.prototype.setColorCfg = function (colorCfg) {
|
||||
this.colorCfg = colorCfg;
|
||||
|
||||
this._updateMetadata();
|
||||
};
|
||||
|
||||
// @api
|
||||
HiPS.prototype.getColorCfg = function () {
|
||||
return this.colorCfg;
|
||||
};
|
||||
|
||||
// @api
|
||||
HiPS.prototype.getOpacity = function () {
|
||||
return this.colorCfg.getOpacity();
|
||||
};
|
||||
|
||||
HiPS.prototype.getAlpha = HiPS.prototype.getOpacity;
|
||||
|
||||
// @api
|
||||
HiPS.prototype.readPixel = function (x, y) {
|
||||
return this.view.wasm.readPixel(x, y, this.layer);
|
||||
};
|
||||
|
||||
HiPS.DEFAULT_SURVEY_ID = "P/DSS2/color";
|
||||
|
||||
return HiPS;
|
||||
|
||||
405
src/js/Image.js
405
src/js/Image.js
@@ -127,7 +127,7 @@ export let Image = (function () {
|
||||
* @param {ImageOptions} [options] - The option for the survey
|
||||
*
|
||||
*/
|
||||
let Image = function(url, options) {
|
||||
function Image(url, options) {
|
||||
// Name of the layer
|
||||
this.layer = null;
|
||||
this.added = false;
|
||||
@@ -149,66 +149,288 @@ export let Image = (function () {
|
||||
let self = this;
|
||||
|
||||
this.query = Promise.resolve(self);
|
||||
}
|
||||
};
|
||||
|
||||
Image.prototype = {
|
||||
/* Precondition: view is already attached */
|
||||
_saveInCache: HiPS.prototype._saveInCache,
|
||||
|
||||
/**
|
||||
* Returns the low and high cuts under the form of a 2 element array
|
||||
*
|
||||
* @memberof Image
|
||||
* @method
|
||||
*
|
||||
* @returns {number[]} The low and high cut values.
|
||||
*/
|
||||
Image.prototype.getCuts = HiPS.prototype.getCuts;
|
||||
|
||||
/**
|
||||
* Sets the opacity factor
|
||||
*
|
||||
* @memberof Image
|
||||
* @method
|
||||
* @param {number} opacity - Opacity of the survey to set. Between 0 and 1
|
||||
*/
|
||||
Image.prototype.setOpacity = HiPS.prototype.setOpacity;
|
||||
|
||||
/**
|
||||
* Set color options generic method for changing colormap, opacity, ...
|
||||
*
|
||||
* @memberof Image
|
||||
* @method
|
||||
* @param {Object} options
|
||||
* @param {number} [options.opacity=1.0] - Opacity of the survey or image (value between 0 and 1).
|
||||
* @param {string} [options.colormap="native"] - The colormap configuration for the survey or image.
|
||||
* @param {string} [options.stretch="linear"] - The stretch configuration for the survey or image.
|
||||
* @param {boolean} [options.reversed=false] - If true, the colormap is reversed; otherwise, it is not reversed.
|
||||
* @param {number} [options.minCut] - The minimum cut value for the color configuration. If not given, 0.0 for JPEG/PNG surveys, the value of the property file for FITS surveys
|
||||
* @param {number} [options.maxCut] - The maximum cut value for the color configuration. If not given, 1.0 for JPEG/PNG surveys, the value of the property file for FITS surveys
|
||||
* @param {boolean} [options.additive=false] - If true, additive blending is applied; otherwise, it is not applied.
|
||||
* @param {number} [options.gamma=1.0] - The gamma correction value for the color configuration.
|
||||
* @param {number} [options.saturation=0.0] - The saturation value for the color configuration.
|
||||
* @param {number} [options.brightness=0.0] - The brightness value for the color configuration.
|
||||
* @param {number} [options.contrast=0.0] - The contrast value for the color configuration.
|
||||
*/
|
||||
Image.prototype.setOptions = HiPS.prototype.setOptions;
|
||||
// @api
|
||||
getCuts: HiPS.prototype.getCuts,
|
||||
Image.prototype.setBlendingConfig = HiPS.prototype.setBlendingConfig;
|
||||
|
||||
// @api
|
||||
setOpacity: HiPS.prototype.setOpacity,
|
||||
/**
|
||||
* Set the colormap of an image
|
||||
*
|
||||
* @memberof Image
|
||||
* @method
|
||||
* @param {string} [colormap="grayscale"] - The colormap label to use. See {@link https://matplotlib.org/stable/users/explain/colors/colormaps.html|here} for more info about colormaps.
|
||||
* Possible values are:
|
||||
* <br>"blues"
|
||||
* <br>"cividis"
|
||||
* <br>"cubehelix"
|
||||
* <br>"eosb"
|
||||
* <br>"grayscale"
|
||||
* <br>"inferno"
|
||||
* <br>"magma"
|
||||
* <br>"native"
|
||||
* <br>"parula"
|
||||
* <br>"plasma"
|
||||
* <br>"rainbow"
|
||||
* <br>"rdbu"
|
||||
* <br>"rdylbu"
|
||||
* <br>"redtemperature"
|
||||
* <br>"sinebow"
|
||||
* <br>"spectral"
|
||||
* <br>"summer"
|
||||
* <br>"viridis"
|
||||
* <br>"ylgnbu"
|
||||
* <br>"ylorbr"
|
||||
* <br>"red"
|
||||
* <br>"green"
|
||||
* <br>"blue"
|
||||
* @param {Object} [options] - Options for the colormap
|
||||
* @param {string} [options.stretch] - Stretching function of the colormap. Possible values are 'linear', 'asinh', 'log', 'sqrt', 'pow'. If no given, will not change it.
|
||||
* @param {boolean} [options.reversed=false] - Reverse the colormap axis.
|
||||
*/
|
||||
Image.prototype.setColormap = HiPS.prototype.setColormap;
|
||||
|
||||
/**
|
||||
* Set the cuts of the image
|
||||
*
|
||||
* @memberof Image
|
||||
* @method
|
||||
* @param {number} minCut - The low cut value.
|
||||
* @param {number} maxCut - The high cut value.
|
||||
*/
|
||||
Image.prototype.setCuts = HiPS.prototype.setCuts;
|
||||
|
||||
// @api
|
||||
setOptions: HiPS.prototype.setOptions,
|
||||
// @api
|
||||
setBlendingConfig: HiPS.prototype.setBlendingConfig,
|
||||
/**
|
||||
* Sets the gamma correction factor.
|
||||
*
|
||||
* This method updates the gamma.
|
||||
*
|
||||
* @memberof Image
|
||||
* @method
|
||||
* @param {number} gamma - The saturation value to set for the image. Between 0.1 and 10
|
||||
*/
|
||||
Image.prototype.setGamma = HiPS.prototype.setGamma;
|
||||
|
||||
// @api
|
||||
setColormap: HiPS.prototype.setColormap,
|
||||
/**
|
||||
* Sets the saturation.
|
||||
*
|
||||
* This method updates the saturation.
|
||||
*
|
||||
* @memberof Image
|
||||
* @method
|
||||
* @param {number} saturation - The saturation value. Between 0 and 1
|
||||
*/
|
||||
Image.prototype.setSaturation = HiPS.prototype.setSaturation;
|
||||
|
||||
// @api
|
||||
setCuts: HiPS.prototype.setCuts,
|
||||
/**
|
||||
* Sets the brightness.
|
||||
*
|
||||
* This method updates the brightness.
|
||||
*
|
||||
* @memberof Image
|
||||
* @method
|
||||
* @param {number} brightness - The brightness value. Between 0 and 1
|
||||
*/
|
||||
Image.prototype.setBrightness = HiPS.prototype.setBrightness;
|
||||
|
||||
// @api
|
||||
setGamma: HiPS.prototype.setGamma,
|
||||
/**
|
||||
* Sets the contrast.
|
||||
*
|
||||
* This method updates the contrast and triggers the update of metadata.
|
||||
*
|
||||
* @memberof Image
|
||||
* @method
|
||||
* @param {number} contrast - The contrast value. Between 0 and 1
|
||||
*/
|
||||
Image.prototype.setContrast = HiPS.prototype.setContrast;
|
||||
|
||||
// @api
|
||||
setSaturation: HiPS.prototype.setSaturation,
|
||||
|
||||
setBrightness: HiPS.prototype.setBrightness,
|
||||
|
||||
setContrast: HiPS.prototype.setContrast,
|
||||
|
||||
// @api
|
||||
toggle: HiPS.prototype.toggle,
|
||||
// @oldapi
|
||||
setAlpha: HiPS.prototype.setOpacity,
|
||||
/**
|
||||
* Toggle the image turning its opacity to 0 back and forth
|
||||
*
|
||||
* @memberof Image
|
||||
* @method
|
||||
*/
|
||||
Image.prototype.toggle = HiPS.prototype.toggle;
|
||||
/**
|
||||
* Old method for setting the opacity use {@link Image#setOpacity} instead
|
||||
*
|
||||
* @memberof Image
|
||||
* @deprecated
|
||||
*/
|
||||
Image.prototype.setAlpha = HiPS.prototype.setOpacity;
|
||||
|
||||
setColorCfg: HiPS.prototype.setColorCfg,
|
||||
Image.prototype.getColorCfg = HiPS.prototype.getColorCfg;
|
||||
|
||||
// @api
|
||||
getColorCfg: HiPS.prototype.getColorCfg,
|
||||
/**
|
||||
* Get the opacity of the image layer
|
||||
*
|
||||
* @memberof HiPS
|
||||
*
|
||||
* @returns {number} The opacity of the layer
|
||||
*/
|
||||
Image.prototype.getOpacity = HiPS.prototype.getOpacity;
|
||||
/**
|
||||
* Use {@link Image#getOpacity}
|
||||
*
|
||||
* @memberof Image
|
||||
* @method
|
||||
* @deprecated
|
||||
*/
|
||||
Image.prototype.getAlpha = HiPS.prototype.getOpacity;
|
||||
|
||||
// @api
|
||||
getOpacity: HiPS.prototype.getOpacity,
|
||||
getAlpha: HiPS.prototype.getOpacity,
|
||||
|
||||
// @api
|
||||
readPixel: HiPS.prototype.readPixel,
|
||||
/**
|
||||
* Read a specific screen pixel value
|
||||
*
|
||||
* @todo This has not yet been implemented
|
||||
* @memberof Image
|
||||
* @method
|
||||
* @param {number} x - x axis in screen pixels to probe
|
||||
* @param {number} y - y axis in screen pixels to probe
|
||||
* @returns {number} the value of that pixel
|
||||
*/
|
||||
Image.prototype.readPixel = HiPS.prototype.readPixel;
|
||||
|
||||
// Private method for updating the view with the new meta
|
||||
_updateMetadata: HiPS.prototype._updateMetadata,
|
||||
|
||||
setView: function (view) {
|
||||
|
||||
/** PRIVATE METHODS **/
|
||||
Image.prototype._setView = function (view) {
|
||||
this.view = view;
|
||||
this._saveInCache();
|
||||
},
|
||||
};
|
||||
|
||||
_addFITS: function(layer) {
|
||||
// FITS images does not mean to be used for storing planetary data
|
||||
Image.prototype.isPlanetaryBody = function () {
|
||||
return false;
|
||||
};
|
||||
|
||||
// @api
|
||||
Image.prototype.focusOn = function () {
|
||||
// ensure the fits have been parsed
|
||||
if (this.added) {
|
||||
this.view.aladin.gotoRaDec(this.ra, this.dec);
|
||||
this.view.aladin.setFoV(this.fov);
|
||||
}
|
||||
};
|
||||
|
||||
/* Private method view is already attached */
|
||||
Image.prototype._saveInCache = HiPS.prototype._saveInCache;
|
||||
|
||||
// Private method for updating the view with the new meta
|
||||
Image.prototype._updateMetadata = HiPS.prototype._updateMetadata;
|
||||
|
||||
Image.prototype._add = function (layer) {
|
||||
this.layer = layer;
|
||||
|
||||
let self = this;
|
||||
let promise;
|
||||
|
||||
if (this.imgFormat === 'fits') {
|
||||
promise = this._addFITS(layer)
|
||||
.catch(e => {
|
||||
console.error(`Image located at ${this.url} could not be parsed as fits file. Is the imgFormat specified correct?`)
|
||||
return Promise.reject(e)
|
||||
})
|
||||
} else if (this.imgFormat === 'jpeg' || this.imgFormat === 'png') {
|
||||
promise = this._addJPGOrPNG(layer)
|
||||
.catch(e => {
|
||||
console.error(`Image located at ${this.url} could not be parsed as a ${this.imgFormat} file. Is the imgFormat specified correct?`);
|
||||
return Promise.reject(e)
|
||||
})
|
||||
} else {
|
||||
// imgformat not defined we will try first supposing it is a fits file and then use the jpg heuristic
|
||||
promise = self._addFITS(layer)
|
||||
.catch(e => {
|
||||
return self._addJPGOrPNG(layer)
|
||||
.catch(e => {
|
||||
console.error(`Image located at ${self.url} could not be parsed as jpg/png/tif image file. Aborting...`)
|
||||
return Promise.reject(e);
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
promise = promise.then((imageParams) => {
|
||||
self.formats = [self.imgFormat];
|
||||
|
||||
// There is at least one entry in imageParams
|
||||
self.added = true;
|
||||
self._setView(self.view);
|
||||
|
||||
// Set the automatic computed cuts
|
||||
let [minCut, maxCut] = self.getCuts();
|
||||
minCut = minCut || imageParams.min_cut;
|
||||
maxCut = maxCut || imageParams.max_cut;
|
||||
self.setCuts(
|
||||
minCut,
|
||||
maxCut
|
||||
);
|
||||
|
||||
self.ra = imageParams.centered_fov.ra;
|
||||
self.dec = imageParams.centered_fov.dec;
|
||||
self.fov = imageParams.centered_fov.fov;
|
||||
|
||||
// Call the success callback on the first HDU image parsed
|
||||
if (self.successCallback) {
|
||||
self.successCallback(
|
||||
self.ra,
|
||||
self.dec,
|
||||
self.fov,
|
||||
self
|
||||
);
|
||||
}
|
||||
|
||||
return self;
|
||||
})
|
||||
.catch((e) => {
|
||||
// This error result from a promise
|
||||
// If I throw it, it will not be catched because
|
||||
// it is run async
|
||||
self.view.removeImageLayer(layer);
|
||||
|
||||
return Promise.reject(e);
|
||||
});
|
||||
|
||||
return promise;
|
||||
};
|
||||
|
||||
Image.prototype._addFITS = function(layer) {
|
||||
let self = this;
|
||||
|
||||
return Utils.fetch({
|
||||
@@ -251,9 +473,9 @@ export let Image = (function () {
|
||||
|
||||
return Promise.resolve(imageParams);
|
||||
})
|
||||
},
|
||||
};
|
||||
|
||||
_addJPGOrPNG: function(layer) {
|
||||
Image.prototype._addJPGOrPNG = function(layer) {
|
||||
let self = this;
|
||||
let img = document.createElement('img');
|
||||
|
||||
@@ -352,96 +574,7 @@ export let Image = (function () {
|
||||
.finally(() => {
|
||||
img.remove();
|
||||
});
|
||||
},
|
||||
|
||||
add: function (layer) {
|
||||
this.layer = layer;
|
||||
|
||||
let self = this;
|
||||
let promise;
|
||||
|
||||
if (this.imgFormat === 'fits') {
|
||||
promise = this._addFITS(layer)
|
||||
.catch(e => {
|
||||
console.error(`Image located at ${this.url} could not be parsed as fits file. Is the imgFormat specified correct?`)
|
||||
return Promise.reject(e)
|
||||
})
|
||||
} else if (this.imgFormat === 'jpeg' || this.imgFormat === 'png') {
|
||||
promise = this._addJPGOrPNG(layer)
|
||||
.catch(e => {
|
||||
console.error(`Image located at ${this.url} could not be parsed as a ${this.imgFormat} file. Is the imgFormat specified correct?`);
|
||||
return Promise.reject(e)
|
||||
})
|
||||
} else {
|
||||
// imgformat not defined we will try first supposing it is a fits file and then use the jpg heuristic
|
||||
promise = self._addFITS(layer)
|
||||
.catch(e => {
|
||||
return self._addJPGOrPNG(layer)
|
||||
.catch(e => {
|
||||
console.error(`Image located at ${self.url} could not be parsed as jpg/png/tif image file. Aborting...`)
|
||||
return Promise.reject(e);
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
promise = promise.then((imageParams) => {
|
||||
self.formats = [self.imgFormat];
|
||||
|
||||
// There is at least one entry in imageParams
|
||||
self.added = true;
|
||||
self.setView(self.view);
|
||||
|
||||
// Set the automatic computed cuts
|
||||
let [minCut, maxCut] = self.getCuts();
|
||||
minCut = minCut || imageParams.min_cut;
|
||||
maxCut = maxCut || imageParams.max_cut;
|
||||
self.setCuts(
|
||||
minCut,
|
||||
maxCut
|
||||
);
|
||||
|
||||
self.ra = imageParams.centered_fov.ra;
|
||||
self.dec = imageParams.centered_fov.dec;
|
||||
self.fov = imageParams.centered_fov.fov;
|
||||
|
||||
// Call the success callback on the first HDU image parsed
|
||||
if (self.successCallback) {
|
||||
self.successCallback(
|
||||
self.ra,
|
||||
self.dec,
|
||||
self.fov,
|
||||
self
|
||||
);
|
||||
}
|
||||
|
||||
return self;
|
||||
})
|
||||
.catch((e) => {
|
||||
// This error result from a promise
|
||||
// If I throw it, it will not be catched because
|
||||
// it is run async
|
||||
self.view.removeImageLayer(layer);
|
||||
|
||||
return Promise.reject(e);
|
||||
});
|
||||
|
||||
return promise;
|
||||
},
|
||||
|
||||
// FITS images does not mean to be used for storing planetary data
|
||||
isPlanetaryBody: function () {
|
||||
return false;
|
||||
},
|
||||
|
||||
// @api
|
||||
focusOn: function () {
|
||||
// ensure the fits have been parsed
|
||||
if (this.added) {
|
||||
this.view.aladin.gotoRaDec(this.ra, this.dec);
|
||||
this.view.aladin.setFoV(this.fov);
|
||||
}
|
||||
},
|
||||
};
|
||||
};
|
||||
|
||||
return Image;
|
||||
})();
|
||||
|
||||
@@ -1668,7 +1668,7 @@ export let View = (function () {
|
||||
View.prototype.setOverlayImageLayer = function (imageLayer, layer = "overlay") {
|
||||
// set the view to the image layer object
|
||||
// do the properties query if needed
|
||||
imageLayer.setView(this);
|
||||
imageLayer._setView(this);
|
||||
|
||||
// register its promise
|
||||
this.imageLayersBeingQueried.set(layer, imageLayer);
|
||||
@@ -1729,7 +1729,7 @@ export let View = (function () {
|
||||
// to the image layer objet (whether it is an HiPS or an Image)
|
||||
.then((imageLayer) => {
|
||||
// Add to the backend
|
||||
const promise = imageLayer.add(layer);
|
||||
const promise = imageLayer._add(layer);
|
||||
ALEvent.FETCH.dispatchedTo(document, {task});
|
||||
|
||||
return promise;
|
||||
|
||||
@@ -167,7 +167,14 @@ export let Datalink = (function() {
|
||||
let updateSlice = () => {
|
||||
let colorCfg = aladinInstance.getOverlayImageLayer(layer).getColorCfg();
|
||||
let hips = aladinInstance.setOverlayImageLayer(cubeOnTheFlyUrl + idxSlice, layer)
|
||||
hips.setColorCfg(colorCfg)
|
||||
hips.setOptions({
|
||||
opacity: colorCfg.opacity,
|
||||
minCut: colorCfg.minCut,
|
||||
maxCut: colorCfg.maxCut,
|
||||
colormap: colorCfg.colormap,
|
||||
stretch: colorCfg.stretch,
|
||||
reversed: colorCfg.reversed
|
||||
})
|
||||
|
||||
slicer.update({
|
||||
value: idxSlice,
|
||||
|
||||
Reference in New Issue
Block a user