UNPKG

@cquiroz/aladin-lite

Version:
250 lines (196 loc) 7.98 kB
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; });