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(); }