var stars;
var nebulae;
function get_body(body, local_observer) {
const now = new Date;
const observer = new Astronomy.Observer(local_observer.latitude, local_observer.longitude, local_observer.altitude);
const equ_ofdate = Astronomy.Equator(body, now, observer, true, true);
const hor = Astronomy.Horizon(now, observer, equ_ofdate.ra, equ_ofdate.dec, "normal");
const illumination = Astronomy.Illumination(body, now);
const name = body;
body = {}
body.ra = equ_ofdate.ra;
body.dec = equ_ofdate.dec;
body.alt = hor.altitude;
body.az = hor.azimuth;
body.body_name = name;
body.mag = illumination.mag;
body.dist = equ_ofdate.dist;
return body;
}
function draw_clock(sky_view, rc, gc, bc) {
const now = new Date;
const observer = new Astronomy.Observer(local_observer.latitude, local_observer.longitude, local_observer.altitude);
const sun = get_body("Sun", local_observer);
const alt = sun.alt;
const az = sun.az;
var mercury = Astronomy.Equator("Mercury", now, observer, true, true);
var matrix = Astronomy.Rotation_HOR_EQD(now, observer);
var spherical = {lat:alt, lon:az, dist:mercury.dist};
var in_vector = Astronomy.VectorFromHorizon(spherical, now, "normal");
var out_vector = Astronomy.RotateVector(matrix, in_vector);
var equator = Astronomy.EquatorFromVector(out_vector);
var size = 10;
const width = sky_view.offsetWidth;
const height = sky_view.offsetHeight;
const top = height - (90 - alt) / 180 * height - (size / 2);
const left = width - (az / 360 * width - (size / 2));
const symbol = document.getElementById("Clock");
symbol.dataset.ra = equator.ra;
symbol.dataset.dec = equator.dec;
symbol.dataset.alt = alt;
symbol.dataset.az = az;
symbol.dataset.type = "clock";
symbol.style.position = "absolute";
symbol.style.left = left;
symbol.style.top = top;
svg = '';
symbol.innerHTML = string_format(svg, size, size / 2, rc, gc, bc);
}
function draw_body(sky_view, body, rc, gc, bc) {
var size = 20;
const m = (41.3 + (body.mag - 14.5)) * 4;
if (m > 1) {size = size * 75 / m}
if (m > 100) {size = 10}
const width = sky_view.offsetWidth;
const height = sky_view.offsetHeight;
const top = height - (90 + body.alt) / 180 * height - (size / 2);
const left = body.az / 360 * width - (size / 2);
const symbol = document.getElementById(body.body_name);
symbol.dataset.ra = body.ra;
symbol.dataset.dec = body.dec;
symbol.dataset.alt = body.alt;
symbol.dataset.az = body.az;
symbol.dataset.dist = body.dist;
symbol.dataset.body_name = body.body_name;
symbol.dataset.mag = Math.round(body.mag * 10) / 10;
symbol.dataset.type = "body";
symbol.style.position = "absolute";
symbol.style.left = left;
symbol.style.top = top;
svg = '';
if (body.body_name == "Moon") {
symbol.innerHTML = string_format(svg, size, size / 2, rc, gc, bc);
} else {
symbol.innerHTML = string_format(svg, size, size / 2, rc - m, gc - m, bc - m);
}
}
function draw_star(sky_view, star, initial) {
var size = 4;
if (star.mag > 2.5) {size = 2}
if (star.mag <= 1.5) {size = 6}
if (star.mag <= 0.5) {size = 8}
const now = new Date;
const observer = new Astronomy.Observer(local_observer.latitude, local_observer.longitude, local_observer.altitude);
const hor = Astronomy.Horizon(now, observer, star.ra, star.dec, "normal");
const width = sky_view.offsetWidth;
const height = sky_view.offsetHeight;
const top = height - (90 + hor.altitude) / 180 * height - (size / 2);
const left = hor.azimuth / 360 * width - (size / 2);
var symbol;
if (initial) {
symbol = document.createElement("div");
symbol.id = star.id
symbol.dataset.ra = star.ra;
symbol.dataset.dec = star.dec;
symbol.dataset.star_name = star.star_name;
symbol.dataset.mag = star.mag;
symbol.dataset.type = "star";
symbol.style.position = "absolute";
} else {
symbol = document.getElementById(star.id);
}
symbol.dataset.alt = hor.altitude;
symbol.dataset.az = hor.azimuth;
symbol.style.left = left;
symbol.style.top = top;
var m, rc, gc, bc;
if (star.mag < 2.5) {
m = (symbol.dataset.mag - 2.5) * 40;
rc = Math.min(100 - m, 255);
gc = Math.min(100 - m, 255);
bc = Math.min(100 - m, 255);
} else {
rc = 128;
gc = 128;
bc = 128;
}
if (initial) {
svg = '';
symbol.innerHTML = string_format(svg, size, size / 2, rc, gc, bc);
sky_view.appendChild(symbol);
symbol.addEventListener("mousemove", e => {
show_nav_data(symbol);
});
symbol.addEventListener("mouseout", e => {
hide_nav_data();
});
symbol.addEventListener("click", e => {
mount_goto_body(symbol);
});
}
}
function draw_nebula(sky_view, nebula, initial) {
var size = 6;
const now = new Date;
const observer = new Astronomy.Observer(local_observer.latitude, local_observer.longitude, local_observer.altitude);
const hor = Astronomy.Horizon(now, observer, nebula.ra, nebula.dec, "normal");
const width = sky_view.offsetWidth;
const height = sky_view.offsetHeight;
const top = height - (90 + hor.altitude) / 180 * height - (size / 2);
const left = hor.azimuth / 360 * width - (size / 2);
var symbol;
if (initial) {
symbol = document.createElement("div");
symbol.id = nebula.id
symbol.dataset.ra = nebula.ra;
symbol.dataset.dec = nebula.dec;
symbol.dataset.nebula_name = nebula.nebula_name;
symbol.dataset.mag = nebula.mag;
symbol.dataset.type = "nebula";
symbol.dataset.dist = nebula.dist;
symbol.dataset.VIEWING_SEASON = nebula.VIEWING_SEASON;
symbol.style.position = "absolute";
} else {
symbol = document.getElementById(nebula.id);
}
if (symbol != null) {
symbol.dataset.alt = hor.altitude;
symbol.dataset.az = hor.azimuth;
symbol.style.left = left;
symbol.style.top = top;
const rc = 200;
const gc = 50;
const bc = 50;
if (initial) {
svg = '';
symbol.innerHTML = string_format(svg, size, size / 2, rc, gc, bc);
sky_view.appendChild(symbol);
symbol.addEventListener("mousemove", e => {
show_nav_data(symbol);
});
symbol.addEventListener("mouseout", e => {
hide_nav_data();
});
symbol.addEventListener("click", e => {
mount_goto_body(symbol);
});
}
}
}
function draw_mount(sky_view, color) {
const width = sky_view.offsetWidth;
const height = sky_view.offsetHeight;
const top = height - (90 + mount.alt) / 180 * height - 10;
const left = mount.az / 360 * width - 10;
const symbol = document.getElementById("Mount");
symbol.dataset.ra = mount.ra;
symbol.dataset.dec = mount.dec;
symbol.dataset.alt = mount.alt;
symbol.dataset.az = mount.az;
symbol.dataset.body_name = mount.body_name;
symbol.dataset.type = "mount";
symbol.style.position = "absolute";
symbol.style.left = left;
symbol.style.top = top;
symbol.innerHTML = string_format('', color);
}
function equatorial_origin(local_observer) {
const now = new Date;
const observer = new Astronomy.Observer(local_observer.latitude, local_observer.longitude, local_observer.altitude);
const horizon = Astronomy.Horizon(now, observer, 0, 0, false);
const sky_view = document.getElementById("sky_view");
const width = sky_view.offsetWidth;
const height = sky_view.offsetHeight;
const ra_line = document.getElementById("ra_line");
// Vertical line moves east -> west.
ra_line.style.position = "absolute";
ra_line.style.top = height / 2 - 10;
ra_line.style.left = horizon.azimuth / 360 * width;
ra_line.style.display = "block";
ra_line.dataset.az = horizon.azimuth;
ra_line.dataset.type = "ra_line";
const dec_line = document.getElementById("dec_line");
// Horizontal line moves north to south.
dec_line.style.position = "absolute";
dec_line.style.top = height - (90 + horizon.altitude) / 180 * height;
dec_line.style.left = width / 2 -10;
dec_line.style.display = "block";
dec_line.dataset.alt = horizon.altitude;
dec_line.dataset.type = "dec_line";
}
function show_nav_data(e) {
const nav = document.getElementById("nav");
const nf22 = Intl.NumberFormat("en-IN", { minimumIntegerDigits: 2, minimumFractionDigits: 2, maximumFractionDigits: 2 });
const nf2 = Intl.NumberFormat("en-IN", { minimumIntegerDigits: 2, minimumFractionDigits: 4, maximumFractionDigits: 4 });
const nf3 = Intl.NumberFormat("en-IN", { minimumIntegerDigits: 3, minimumFractionDigits: 3, maximumFractionDigits: 3 });
nav_data = "";
if (e.dataset.type == "ra_line") {
nav_data = "Right ascension of equatorial origin at azimuth: " + nf2.format(e.dataset.az);
}
if (e.dataset.type == "dec_line") {
nav_data = "Declination of equatorial origin at altitude: " + nf2.format(e.dataset.alt);
}
if (e.dataset.type == "rise_line") {
nav_data = "Sun rises at azimuth: " + nf2.format(e.dataset.az) + ", day time: " + Math.round(e.dataset.day_time * 100) + "%";
}
if (e.dataset.type == "set_line") {
nav_data = "Sun sets at azimuth: " + nf2.format(e.dataset.az) + ", day time: " + Math.round(e.dataset.day_time * 100) + "%";
}
if (e.dataset.type == "top_line") {
nav_data = "Sun is at it's highest at altitude: " + nf2.format(e.dataset.alt);
}
if (e.dataset.type == "mount") {
nav_data = string_format("Alt: {0}, az: {1}, ra: {2}, dec: {3}, mag: {4}, name: {5}.",
nf2.format(e.dataset.alt), nf3.format(e.dataset.az), nf2.format(e.dataset.ra), nf3.format(e.dataset.dec),
e.dataset.mag, e.dataset.body_name);
}
if (e.dataset.type == "body") {
nav_data = string_format("Alt: {0}, az: {1}, ra: {2}, dec: {3}, dist: {4} au, mag: {5}, name: {6}.",
nf2.format(e.dataset.alt), nf3.format(e.dataset.az), nf2.format(e.dataset.ra), nf3.format(e.dataset.dec),
nf22.format(e.dataset.dist), e.dataset.mag, e.dataset.body_name);
}
if (e.dataset.type == "star") {
nav_data = string_format("Alt: {0}, az: {1}, ra: {2}, dec: {3}, mag: {4}, name: {5}.",
nf2.format(e.dataset.alt), nf3.format(e.dataset.az), nf2.format(e.dataset.ra), nf3.format(e.dataset.dec),
e.dataset.mag, e.dataset.star_name);
}
if (e.dataset.type == "nebula") {
nav_data = string_format("Alt: {0}, az: {1}, ra: {2}, dec: {3}, mag: {4}, name: {5}, dist: {6} ly, viewing season: {7}.",
nf2.format(e.dataset.alt), nf3.format(e.dataset.az), nf2.format(e.dataset.ra), nf3.format(e.dataset.dec),
e.dataset.mag, e.dataset.nebula_name, e.dataset.dist.replaceAll(',', ''), e.dataset.VIEWING_SEASON);
}
if (e.dataset.type == "clock") {
nav_data = string_format("Shadow from Earth is deepest in this direction.");
}
nav.innerHTML = nav_data;
}
function hide_nav_data(e) {
const nav = document.getElementById("nav");
nav.innerHTML = "";
}
function get_stars() {
const xhttp = new XMLHttpRequest();
xhttp.onload = function() {
stars = JSON.parse(this.responseText);
for(index in stars) {
draw_star(sky_view, stars[index], true);
}
}
xhttp.open("GET", "/get_stars?magnitude=" + 3.5, true);
xhttp.send();
}
function get_nebulae() {
const xhttp = new XMLHttpRequest();
xhttp.onload = function() {
nebulae = JSON.parse(this.responseText);
for(index in nebulae) {
draw_nebula(sky_view, nebulae[index], true);
}
}
xhttp.open("GET", "/get_nebulae?VIEWING_DIFFICULTY=" + "Easy", true);
xhttp.send();
}