celestial-chart 0.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/src/get.js ADDED
@@ -0,0 +1,210 @@
1
+
2
+ import { Kepler } from "./kepler.js";
3
+ import { Celestial } from "./core.js";
4
+ import { euler, transformDeg } from "./transform.js";
5
+ import { has, isArray, isNumber } from "./util.js";
6
+
7
+ //load data and transform coordinates
8
+
9
+
10
+ function getPoint(coords, trans) {
11
+ return transformDeg(coords, euler[trans]);
12
+ }
13
+
14
+ function getData(d, trans) {
15
+ if (trans === "equatorial") return d;
16
+
17
+ var leo = euler[trans],
18
+ f = d.features;
19
+
20
+ for (var i=0; i<f.length; i++)
21
+ f[i].geometry.coordinates = translate(f[i], leo);
22
+
23
+ return d;
24
+ }
25
+
26
+ // These also receive the map instance: the planet list and the grid values
27
+ // depend on that map's own configuration, not on a shared "current map".
28
+ function getPlanets(d, sky) {
29
+ var res = [];
30
+
31
+ for (var key in d) {
32
+ if (!has(d, key)) continue;
33
+ if (sky.cfg.planets.which.indexOf(key) === -1) continue;
34
+ var dat = Kepler().id(key);
35
+ if (has(d[key], "parent")) dat.parentBody(d[key].parent);
36
+ dat.elements(d[key].elements[0]).params(d[key]);
37
+ if (key === "ter")
38
+ Celestial.origin = dat;
39
+ else res.push(dat);
40
+ }
41
+ //res.push(Kepler().id("sol"));
42
+ //res.push(Kepler().id("lun"));
43
+ return res;
44
+ }
45
+
46
+
47
+ function getPlanet(id, dt, sky) {
48
+ dt = dt || Celestial.date();
49
+ if (!Celestial.origin) return;
50
+
51
+ var o = Celestial.origin(dt).spherical(), res;
52
+
53
+ sky.container.selectAll(".planet").each(function(d) {
54
+ if (id === d.id()) {
55
+ res = d(dt).equatorial(o);
56
+ }
57
+ });
58
+ return res;
59
+ }
60
+
61
+ function getConstellationList(d) {
62
+ var res = {},
63
+ f = d.features;
64
+
65
+ for (var i=0; i<f.length; i++) {
66
+ res[f[i].id] = {
67
+ center: f[i].properties.display.slice(0,2),
68
+ scale: f[i].properties.display[2]
69
+ };
70
+ }
71
+ return res;
72
+ }
73
+
74
+ function getMwbackground(d) {
75
+ // geoJson object to darken the mw-outside, prevent greying of whole map in some orientations
76
+ var res = {'type': 'FeatureCollection', 'features': [ {'type': 'Feature',
77
+ 'geometry': { 'type': 'MultiPolygon', 'coordinates' : [] }
78
+ }]};
79
+
80
+ // reverse the polygons, inside -> outside
81
+ var l1 = d.features[0].geometry.coordinates[0];
82
+ res.features[0].geometry.coordinates[0] = [];
83
+ for (var i=0; i<l1.length; i++) {
84
+ res.features[0].geometry.coordinates[0][i] = l1[i].slice().reverse();
85
+ }
86
+
87
+ return res;
88
+ }
89
+
90
+ function getTimezones() {
91
+
92
+ }
93
+
94
+ function translate(d, leo) {
95
+ var res = [];
96
+ switch (d.geometry.type) {
97
+ case "Point": res = transformDeg(d.geometry.coordinates, leo); break;
98
+ case "LineString": res.push(transLine(d.geometry.coordinates, leo)); break;
99
+ case "MultiLineString": res = transMultiLine(d.geometry.coordinates, leo); break;
100
+ case "Polygon": res.push(transLine(d.geometry.coordinates[0], leo)); break;
101
+ case "MultiPolygon": res.push(transMultiLine(d.geometry.coordinates[0], leo)); break;
102
+ }
103
+
104
+ return res;
105
+ }
106
+
107
+ function getGridValues(type, loc, sky) {
108
+ var lines = [];
109
+ if (!loc) return [];
110
+ if (!isArray(loc)) loc = [loc];
111
+ //center, outline, values
112
+ for (var i=0; i < loc.length; i++) {
113
+ switch (loc[i]) {
114
+ case "center":
115
+ if (type === "lat")
116
+ lines = lines.concat(getLine(type, sky.cfg.center[0], "N"));
117
+ else
118
+ lines = lines.concat(getLine(type, sky.cfg.center[1], "S"));
119
+ break;
120
+ case "outline":
121
+ if (type === "lon") {
122
+ lines = lines.concat(getLine(type, sky.cfg.center[1]-89.99, "S"));
123
+ lines = lines.concat(getLine(type, sky.cfg.center[1]+89.99, "N"));
124
+ } else {
125
+ // TODO: hemi
126
+ lines = lines.concat(getLine(type, sky.cfg.center[0]-179.99, "E"));
127
+ lines = lines.concat(getLine(type, sky.cfg.center[0]+179.99, "W"));
128
+ }
129
+ break;
130
+ default: if (isNumber(loc[i])) {
131
+ if (type === "lat")
132
+ lines = lines.concat(getLine(type, loc[i], "N"));
133
+ else
134
+ lines = lines.concat(getLine(type, loc[i], "S"));
135
+ break;
136
+ }
137
+ }
138
+ }
139
+ //return [{coordinates, value, orientation}, ...]
140
+ return jsonGridValues(lines);
141
+ }
142
+
143
+ function jsonGridValues(lines) {
144
+ var res = [];
145
+ for (var i=0; i < lines.length; i++) {
146
+ var f = {type: "Feature", "id":i, properties: {}, geometry:{type:"Point"}};
147
+ f.properties.value = lines[i].value;
148
+ f.properties.orientation = lines[i].orientation;
149
+ f.geometry.coordinates = lines[i].coordinates;
150
+ res.push(f);
151
+ }
152
+ return res;
153
+ }
154
+
155
+ function getLine(type, loc, orient) {
156
+ var min, max, step, val, coord,
157
+ tp = type,
158
+ res = [],
159
+ lr = loc;
160
+ if (sky.cfg.transform === "equatorial" && tp === "lon") tp = "ra";
161
+
162
+ if (tp === "ra") {
163
+ min = 0; max = 23; step = 1;
164
+ } else if (tp === "lon") {
165
+ min = 0; max = 350; step = 10;
166
+ } else {
167
+ min = -80; max = 80; step = 10;
168
+ }
169
+ for (var i=min; i<=max; i+=step) {
170
+ var o = orient;
171
+ if (tp === "lat") {
172
+ coord = [lr, i];
173
+ val = i.toString() + "\u00b0";
174
+ if (i < 0) o += "S"; else o += "N";
175
+ } else if (tp === "ra") {
176
+ coord = [i * 15, lr];
177
+ val = i.toString() + "\u02b0";
178
+ } else {
179
+ coord = [i, lr];
180
+ val = i.toString() + "\u00b0";
181
+ }
182
+
183
+ res.push({coordinates: coord, value: val, orientation: o});
184
+ }
185
+ return res;
186
+ }
187
+
188
+ function transLine(c, leo) {
189
+ var line = [];
190
+
191
+ for (var i=0; i<c.length; i++)
192
+ line.push(transformDeg(c[i], leo));
193
+
194
+ return line;
195
+ }
196
+
197
+ function transMultiLine(c, leo) {
198
+ var lines = [];
199
+
200
+ for (var i=0; i<c.length; i++)
201
+ lines.push(transLine(c[i], leo));
202
+
203
+ return lines;
204
+ }
205
+
206
+ Celestial.getData = getData;
207
+ Celestial.getPoint = getPoint;
208
+ Celestial.getPlanet = getPlanet;
209
+
210
+ export { getConstellationList, getData, getGridValues, getMwbackground, getPlanet, getPlanets };
package/src/global.js ADDED
@@ -0,0 +1,4 @@
1
+ // Browser entry point: the original, global `Celestial` interface.
2
+ // D3 is bundled in, so no separate script tag is needed.
3
+ import { Celestial } from "./celestial.js";
4
+ window.Celestial = Celestial;
@@ -0,0 +1,98 @@
1
+ import { Celestial } from "./core.js";
2
+ import { deg2rad } from "./transform.js";
3
+
4
+ var horizontal = function(dt, pos, loc) {
5
+ //dt: datetime, pos: celestial coordinates [lat,lng], loc: location [lat,lng]
6
+ var ha = getMST(dt, loc[1]) - pos[0];
7
+ if (ha < 0) ha = ha + 360;
8
+
9
+ ha = ha * deg2rad;
10
+ var dec = pos[1] * deg2rad;
11
+ var lat = loc[0] * deg2rad;
12
+
13
+ var alt = Math.asin(Math.sin(dec) * Math.sin(lat) + Math.cos(dec) * Math.cos(lat) * Math.cos(ha));
14
+ var az = Math.acos((Math.sin(dec) - Math.sin(alt) * Math.sin(lat)) / (Math.cos(alt) * Math.cos(lat)));
15
+
16
+ if (Math.sin(ha) > 0) az = Math.PI * 2 - az;
17
+
18
+ return [alt / deg2rad, az / deg2rad, 0];
19
+ };
20
+
21
+ horizontal.inverse = function(dt, hor, loc) {
22
+
23
+ var alt = hor[0] * deg2rad;
24
+ var az = hor[1] * deg2rad;
25
+ var lat = loc[0] * deg2rad;
26
+
27
+ var dec = Math.asin((Math.sin(alt) * Math.sin(lat)) + (Math.cos(alt) * Math.cos(lat) * Math.cos(az)));
28
+ var ha = (Math.sin(alt) - (Math.sin(dec) * Math.sin(lat))) / (Math.cos(dec) * Math.cos(lat));
29
+
30
+ // Rounding error can push the quotient outside the domain of acos (at the
31
+ // zenith it comes out as 1+1e-16). The previous .toFixed(6) handled that only
32
+ // by accident, and in doing so truncated the input to six decimals — where
33
+ // acos is steep.
34
+ ha = Math.acos(Math.max(-1, Math.min(1, ha)));
35
+ // acos returns 0..180 degrees, so half the sky would be lost. The forward
36
+ // direction handles the same ambiguity (if (Math.sin(ha) > 0) az = 2*pi - az);
37
+ // the inverse needs its mirror image. See upstream issue #148.
38
+ if (Math.sin(az) > 0) ha = -ha;
39
+ ha = ha / deg2rad;
40
+
41
+ var ra = getMST(dt, loc[1]) - ha;
42
+ //if (ra < 0) ra = ra + 360;
43
+
44
+ return [ra, dec / deg2rad, 0];
45
+ };
46
+
47
+ function getMST(dt, lng)
48
+ {
49
+ var yr = dt.getUTCFullYear();
50
+ var mo = dt.getUTCMonth() + 1;
51
+ var dy = dt.getUTCDate();
52
+ var h = dt.getUTCHours();
53
+ var m = dt.getUTCMinutes();
54
+ var s = dt.getUTCSeconds();
55
+
56
+ if ((mo == 1)||(mo == 2)) {
57
+ yr = yr - 1;
58
+ mo = mo + 12;
59
+ }
60
+
61
+ var a = Math.floor(yr / 100);
62
+ var b = 2 - a + Math.floor(a / 4);
63
+ var c = Math.floor(365.25 * yr);
64
+ var d = Math.floor(30.6001 * (mo + 1));
65
+
66
+ // days since J2000.0
67
+ var jd = b + c + d - 730550.5 + dy + (h + m/60.0 + s/3600.0)/24.0;
68
+
69
+ // julian centuries since J2000.0
70
+ var jt = jd/36525.0;
71
+
72
+ // the mean sidereal time in degrees
73
+ var mst = 280.46061837 + 360.98564736629*jd + 0.000387933*jt*jt - jt*jt*jt/38710000 + lng;
74
+
75
+ // in degrees modulo 360.0
76
+ if (mst > 0.0)
77
+ while (mst > 360.0) mst = mst - 360.0;
78
+ else
79
+ while (mst < 0.0) mst = mst + 360.0;
80
+
81
+ return mst;
82
+ }
83
+
84
+ Celestial.horizontal = horizontal;
85
+ // Hour angle in degrees, in the range [0, 360).
86
+ //
87
+ // The condition was originally `ha < 180`, which is a typo: getMST returns
88
+ // [0, 360) and so does ra, so the difference lies in (-360, 360) — it is values
89
+ // below zero that need wrapping. With `180`, an hour angle of 100 degrees came
90
+ // out as 460. Two lines above, horizontal() has the same normalisation written
91
+ // correctly.
92
+ Celestial.ha = function(dt, lng, ra) {
93
+ var ha = getMST(dt, lng) - ra;
94
+ if (ha < 0) ha = ha + 360;
95
+ return ha;
96
+ };
97
+
98
+ export { horizontal };
package/src/index.js ADDED
@@ -0,0 +1,8 @@
1
+ // ESM entry point.
2
+ //
3
+ // import Celestial from "celestial-chart"; // the original, global interface
4
+ // import { SkyMap } from "celestial-chart"; // for several independent maps
5
+ //
6
+ import { Celestial, SkyMap } from "./celestial.js";
7
+ export { Celestial, SkyMap };
8
+ export default Celestial;