astro_helper.js 8.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246
  1. var AngleMode = "dms";
  2. var RegExp_Float = /^\d+(\.\d*)?([eE][\+\-]?\d+)?$/;
  3. function $(id)
  4. {
  5. return document.getElementById (id);
  6. }
  7. function HtmlRightAscension (ra, mode)
  8. {
  9. if (mode == null) {
  10. mode = AngleMode;
  11. }
  12. switch (mode) {
  13. case "dms":
  14. // 23<sup>h</sup>14<sup>m</sup>16<sup>s</sup>
  15. var dms = Angle.DMS (ra);
  16. if (dms.negative) {
  17. throw "Encountered negative right ascension! " + ra;
  18. }
  19. var hours = (dms.degrees < 10 ? "0" : "") + dms.degrees.toString();
  20. var minutes = (dms.minutes < 10 ? "0" : "") + dms.minutes.toString();
  21. var seconds = (dms.seconds < 10 ? "0" : "") + dms.seconds.toFixed(1);
  22. var s = hours + "<sup class='UnitSup'>h</sup>&nbsp;" + minutes + "<sup class='UnitSup'>m</sup>&nbsp;" + seconds + "<sup class='UnitSup'>s</sup>";
  23. return s;
  24. case "dmm":
  25. // 23<sup>h</sup>14.27<sup>m</sup>
  26. var dms = Angle.DMM (ra);
  27. if (dms.negative) {
  28. throw "Encountered negative right ascension! " + ra;
  29. }
  30. var hours = (dms.degrees < 10 ? "0" : "") + dms.degrees.toString();
  31. var minutes = (dms.minutes < 10 ? "0" : "") + dms.minutes.toFixed(2);
  32. var s = hours + "<sup class='UnitSup'>h</sup>&nbsp;" + minutes + "<sup class='UnitSup'>m</sup>";
  33. return s;
  34. case "decimal":
  35. return ra.toFixed(5) + "<sup class='UnitSup'>h</sup>";
  36. default:
  37. throw "HtmlRightAscension: Unknown angle mode '" + mode + "'";
  38. }
  39. }
  40. function HtmlDeclination (dec, mode)
  41. {
  42. if (mode == null) {
  43. mode = AngleMode;
  44. }
  45. switch (mode) {
  46. case "dms":
  47. var dms = Angle.DMS (dec);
  48. var s = dms.negative ? "&minus;" : "&nbsp;";
  49. if (dms.degrees < 100) {
  50. s += "0";
  51. }
  52. var hours = (dms.degrees < 10 ? "0" : "") + dms.degrees.toString();
  53. var minutes = (dms.minutes < 10 ? "0" : "") + dms.minutes.toString();
  54. var seconds = (dms.seconds < 10 ? "0" : "") + dms.seconds.toFixed(1);
  55. s += hours + "&deg;&nbsp;" + minutes + "'&nbsp;" + seconds + "&quot;";
  56. return s;
  57. case "dmm":
  58. var dms = Angle.DMM (dec);
  59. var s = dms.negative ? "&minus;" : "&nbsp;";
  60. if (dms.degrees < 100) {
  61. s += "0";
  62. }
  63. var hours = (dms.degrees < 10 ? "0" : "") + dms.degrees.toString();
  64. var minutes = (dms.minutes < 10 ? "0" : "") + dms.minutes.toFixed(2);
  65. s += hours + "&deg;&nbsp;" + minutes + "'&nbsp;";
  66. return s;
  67. case "decimal":
  68. return dec.toFixed(5) + "&deg;";
  69. default:
  70. throw "HtmlDeclination: Unknown angle mode '" + mode + "'";
  71. }
  72. }
  73. function HtmlConstellation (eq)
  74. {
  75. var c = Astronomy.FindConstellation (eq);
  76. if (c == null) {
  77. return "<span title='Cannot determine constellation'>???</span>";
  78. } else {
  79. var verboseName = ConstellationByConciseName[c.ConciseName].FullName;
  80. return "<span title='" + verboseName + "'>" + c.ConciseName + "</span>";
  81. }
  82. }
  83. function ShowAngleFeedback (divName, value, editName)
  84. {
  85. var isDMS = ($(editName).value.indexOf(":") >= 0);
  86. var feedback;
  87. if (isDMS) {
  88. // user entered dd:mm:ss, so show feedback in pure decimal
  89. feedback = HtmlDeclination (value, "decimal");
  90. } else {
  91. // user entered pure decimal, so show feedback in dd:mm:ss
  92. feedback = HtmlDeclination (value, "dms");
  93. }
  94. $(divName).innerHTML = '&nbsp;=&nbsp;' + feedback;
  95. }
  96. function CommitGeographicCoordinates()
  97. {
  98. var lat = ParseAngle ($('GeoLat_Value').value);
  99. var lon = ParseAngle ($('GeoLong_Value').value);
  100. if (lat == null) {
  101. alert ("The geographic latitude you have entered is not valid. It must be between 0 and 90 degrees. You may enter it with a decimal fraction, or in ddd:mm:ss notation.");
  102. $('GeoLat_Value').focus();
  103. }
  104. if (lon == null) {
  105. alert ("The geographic longitude you have entered is not valid. It must be between 0 and 180 degrees. You may enter it with a decimal fraction, or in dd:mm:ss notation.");
  106. $('GeoLong_Value').focus();
  107. }
  108. if ((lat != null) && (lon != null)) {
  109. if ($('GeoLat_NS').selectedIndex == 1) {
  110. lat *= -1.0;
  111. }
  112. if ($('GeoLong_EW').selectedIndex == 0) {
  113. lon *= -1.0;
  114. }
  115. GeographicLatitude = lat;
  116. GeographicLongitude = lon;
  117. ShowAngleFeedback ('GeoLat_Feedback', lat, 'GeoLat_Value');
  118. ShowAngleFeedback ('GeoLong_Feedback', lon, 'GeoLong_Value');
  119. return true; // valid
  120. } else {
  121. return false; // not valid
  122. }
  123. }
  124. function SaveGeographicCoordinates()
  125. {
  126. if (CommitGeographicCoordinates()) {
  127. var expiration = 3650; // 10 years
  128. WriteCookie ("GeographicLatitudeValue", $('GeoLat_Value').value, expiration);
  129. WriteCookie ("GeographicLongitudeValue", $('GeoLong_Value').value, expiration);
  130. WriteCookie ("GeographicLatitudeDirection", (($('GeoLat_NS') .selectedIndex == 0) ? "N" : "S"), expiration);
  131. WriteCookie ("GeographicLongitudeDirection", (($('GeoLong_EW').selectedIndex == 0) ? "W" : "E"), expiration);
  132. $('SaveButton').disabled = true;
  133. }
  134. }
  135. function LoadGeographicCoordinates()
  136. {
  137. $('GeoLat_Value').value = ReadCookie ("GeographicLatitudeValue", "27.41305");
  138. $('GeoLong_Value').value = ReadCookie ("GeographicLongitudeValue", "82.66034");
  139. $('GeoLat_NS').selectedIndex = ReadCookie("GeographicLatitudeDirection","N") == "N" ? 0 : 1;
  140. $('GeoLong_EW').selectedIndex = ReadCookie("GeographicLongitudeDirection","W") == "W" ? 0 : 1;
  141. CommitGeographicCoordinates();
  142. }
  143. function OnGeoLatLongChange()
  144. {
  145. $('SaveButton').disabled = false;
  146. }
  147. function ParseAngle (s, max)
  148. {
  149. // Look for 1..3 floating pointer numbers, delimited by colons.
  150. // For example: 37.35 or 43:15.373 or 23:44:55.7
  151. // These represent degrees[:minutes[:seconds]].
  152. // We ignore any white space outside the floating point numbers.
  153. var angle = null;
  154. var array = s.split(/\s*:\s*/);
  155. if (array.length >= 1 && array.length <= 3) {
  156. var denom = 1.0;
  157. angle = 0.0;
  158. for (var i=0; i < array.length; ++i) {
  159. if (!RegExp_Float.test(array[i])) {
  160. return null; // does not look like a valid floating point number
  161. }
  162. var x = parseFloat (array[i]);
  163. if (isNaN(x)) {
  164. return null; // could not parse a floating point number
  165. }
  166. if (x < 0) {
  167. return null; // user must specify direction by using E/W, N/S controls, not '+' or '-'.
  168. }
  169. if (i > 0) {
  170. if (x >= 60.0) {
  171. return null; // not a valid minute or second value
  172. }
  173. }
  174. angle += x / denom;
  175. denom *= 60.0;
  176. }
  177. if (angle < 0.0 || angle > max) {
  178. return null;
  179. }
  180. }
  181. return angle;
  182. }
  183. /*
  184. $Log: astro_helper.js,v $
  185. Revision 1.3 2009/03/08 00:02:10 Don.Cross
  186. My C# astro.exe (compiled as sun.exe) now has a "javascript" option that generates constellation.js.
  187. This new constellation.js file contains the data needed for constellation calculation based on equatorial coordinates.
  188. I updated my astronomy.js code to allow use of this data to determine a constellation.
  189. The page solar_system.html uses this now to show the concise constellation symbol for each celestial body.
  190. Revision 1.2 2008/04/06 21:16:09 Don.Cross
  191. Users seem confused when confronted with the colon-notation the first time entering geographic coordinates.
  192. I am changing the default to a real location (Cambridge, MA) but making it decimal instead of dd:mm:ss.
  193. Revision 1.1 2008/02/22 23:11:29 Don.Cross
  194. Starting to work on graphical sky view in JavaScript.
  195. Factored out some code for managing user's geographic location in cookies and form elements
  196. from solar_system.html into new file astro_helper.js.
  197. Adding star_catalog.js, which was translated from text file by my GenStarMapJS.exe program.
  198. */