@cquiroz/aladin-lite
Version:
AladinLite module
250 lines (196 loc) • 7.98 kB
JavaScript
function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
// Copyright 2016 - UDS/CNRS
// The Aladin Lite program is distributed under the terms
// of the GNU General Public License version 3.
//
// This file is part of Aladin Lite.
//
// Aladin Lite is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, version 3 of the License.
//
// Aladin Lite is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// The GNU General Public License is available in COPYING file
// along with Aladin Lite.
//
/******************************************************************************
* Aladin Lite project
*
* File HpxKey
* This class represents a HEALPix cell
*
* Author: Thomas Boch[CDS]
*
*****************************************************************************/
import Tile from './Tile';
import SpatialVector from './SpatialVector';
import HealpixCache from './HealpixCache';
import AladinUtils from './AladinUtils';
import CooFrameEnum from './CooFrameEnum';
import CooConversion from './CooConversion';
import { UPDATE_NEEDED_TILES_DELAY } from './HpxImageSurvey';
var MAX_PARENTE = 4;
var M = 280 * 280;
var N = 150 * 150;
var RAP = 0.7;
export default class HpxKey {
/** Constructor
*
*/
constructor(norder, npix, hips, width, height, dx, dy, allskyTexture, allskyTextureSize) {
this.norder = norder;
this.npix = npix;
this.nside = Math.pow(2, norder);
this.hips = hips; // survey to which this HpxKey is attached
this.frame = hips.cooFrame; // coordinate frame of the survey to which this HpxKey is attached
this.width = width; // width of the tile
this.height = height; // height of the tile
this.dx = dx || 0; // shift in x (for all-sky tiles)
this.dy = dy || 0; // shift in y (for all-sky tiles)
this.allskyTexture = allskyTexture || undefined;
this.allskyTextureSize = allskyTextureSize;
this.parente = 0; // if this key comes from an ancestor, length of the filiation
this.children = null;
this.ancestor = null; // ancestor having the pixels
} // "static" methods
draw(ctx, view) {
//console.log('Drawing ', this.norder, this.npix);
var n = 0; // number of traced triangles
var corners = this.getProjViewCorners(view);
if (corners == null) {
return 0;
}
var now = new Date().getTime();
var updateNeededTiles = this.ancestor == null && this.norder >= 3 && now - this.hips.lastUpdateDateNeededTiles > 0.1;
try {
if (HpxKey._isTooLarge(corners)) {
//console.log('too large');
var m = this.drawChildren(ctx, view, MAX_PARENTE); // Si aucun sous-losange n'a pu être dessiné, je trace tout de même le père
if (m > 0) {
return m;
}
}
} catch (e) {
return 0;
} // actual drawing
var norder = this.ancestor == null ? this.norder : this.ancestor.norder;
var npix = this.ancestor == null ? this.npix : this.ancestor.npix; //console.log(corners);
//corners = AladinUtils.grow2(corners, 1); // grow by 1 pixel in each direction
//console.log(corners);
var url = this.hips.getTileURL(norder, npix);
var tile = this.hips.tileBuffer.getTile(url);
if (tile && Tile.isImageOk(tile.img) || this.allskyTexture) {
if (!this.allskyTexture && !this.hips.tileSize) {
this.hips.tileSize = tile.img.width;
}
var img = this.allskyTexture || tile.img;
var w = this.allskyTextureSize || img.width;
if (this.parente) {
w = w / Math.pow(2, this.parente);
}
this.hips.drawOneTile2(ctx, img, corners, w, null, this.dx, this.dy, true, norder);
n += 2;
} else if (updateNeededTiles && !tile) {
tile = this.hips.tileBuffer.addTile(url);
view.downloader.requestDownload(tile.img, tile.url, this.hips.useCors);
this.hips.lastUpdateDateNeededTiles = now;
view.requestRedrawAtDate(now + UPDATE_NEEDED_TILES_DELAY + 10);
}
return n;
}
drawChildren(ctx, view, maxParente) {
var n = 0;
var limitOrder = 13; // corresponds to NSIDE=8192, current HealpixJS limit
if (this.width > 1 && this.norder < limitOrder && this.parente < maxParente) {
var children = this.getChildren();
if (children != null) {
for (var i = 0; i < 4; i++) {
//console.log(i);
if (children[i] != null) {
n += children[i].draw(ctx, view, maxParente);
}
}
}
}
return n;
} // returns the 4 HpxKey children
getChildren() {
if (this.children != null) {
return this.children;
}
var children = [];
for (var childNb = 0; childNb < 4; childNb++) {
var child = HpxKey.createHpxKeyfromAncestor(this, childNb);
children[childNb] = child;
}
this.children = children;
return this.children;
}
getProjViewCorners(view) {
var cornersXY = [];
var cornersXYView = [];
var spVec = new SpatialVector();
var corners = HealpixCache.corners_nest(this.npix, this.nside);
var lon, lat;
for (var k = 0; k < 4; k++) {
spVec.setXYZ(corners[k].x, corners[k].y, corners[k].z); // need for frame transformation ?
if (this.frame.system !== view.cooFrame.system) {
if (this.frame.system === CooFrameEnum.SYSTEMS.J2000) {
var radec = CooConversion.J2000ToGalactic([spVec.ra(), spVec.dec()]);
lon = radec[0];
lat = radec[1];
} else if (this.frame.system === CooFrameEnum.SYSTEMS.GAL) {
var _radec = CooConversion.GalacticToJ2000([spVec.ra(), spVec.dec()]);
lon = _radec[0];
lat = _radec[1];
}
} else {
lon = spVec.ra();
lat = spVec.dec();
}
cornersXY[k] = view.projection.project(lon, lat);
}
if (cornersXY[0] == null || cornersXY[1] == null || cornersXY[2] == null || cornersXY[3] == null) {
return null;
}
for (var _k = 0; _k < 4; _k++) {
cornersXYView[_k] = AladinUtils.xyToView(cornersXY[_k].X, cornersXY[_k].Y, view.width, view.height, view.largestDim, view.zoomFactor);
}
return cornersXYView;
} // end of HpxKey.prototype
/** Returns the squared distance for points in array c at indexes g and d
*/
static _dist(c, g, d) {
var dx = c[g].vx - c[d].vx;
var dy = c[g].vy - c[d].vy;
return dx * dx + dy * dy;
}
/** Returns true if the HEALPix rhomb described by its 4 corners (array c)
* is too large to be drawn in one pass ==> need to be subdivided */
static _isTooLarge(c) {
var d1, d2;
if ((d1 = HpxKey._dist(c, 0, 2)) > M || (d2 = HpxKey._dist(c, 2, 1)) > M) {
return true;
}
if (d1 === 0 || d2 === 0) {
throw new Error("Rhomb error");
}
var diag1 = HpxKey._dist(c, 0, 3);
var diag2 = HpxKey._dist(c, 1, 2);
if (diag2 === 0 || diag2 === 0) {
throw new Error("Rhomb error");
}
var rap = diag2 > diag1 ? diag1 / diag2 : diag2 / diag1;
return rap < RAP && (diag1 > N || diag2 > N);
}
}
_defineProperty(HpxKey, "createHpxKeyfromAncestor", function (father, childNb) {
var hpxKey = new HpxKey(father.norder + 1, father.npix * 4 + childNb, father.hips, father.width / 2, father.height / 2, childNb === 2 || childNb === 3 ? father.dx + father.width / 2 : father.dx, childNb === 1 || childNb === 3 ? father.dy + father.height / 2 : father.dy, father.allskyTexture, father.allskyTextureSize);
hpxKey.parente = father.parente + 1;
hpxKey.ancestor = father.ancestor || father;
return hpxKey;
});