 // ===================================================================
 // Gazza's Great Circle Calculator
 // Author: Gary Nicholson <gary@nicholson.co.nz>
 // WWW: http://www.gazza.co.nz/
 //
 // ** bastardized by:  Brian Levetzow for HBD
 //
 // NOTICE: You may use this code for any purpose, commercial or
 // private, without any further permission from the author. You may
 // remove this notice from your final code if you wish, however it is
 // appreciated by the author if at least my web site address is kept.
 //
 // Let me know if you use this on your site and I may link to your site.
 //
 // You may *NOT* re-distribute this code in any way except through its
 // use. That means, you can include it in your product, or your web
 // site, or any other form where the code is actually being used. You
 // may not put the plain javascript up on your site for download or
 // include it in your javascript libraries for download. Instead,
 // please just point to my URL to ensure the most up-to-date versions
 // of the files. Thanks.
 //
 // Permission to use this code without asking first may not apply
 // to other calculators on my site.  If in doubt ask me first.
 //
 // ** Edited and reused with permission - Brian Levetzow <levetzowbt@home.com>
 // ** Reuse limited to generating "Rennerian Coordinates" for members of HBD.
 // ** Several items were significantly modified from the original code.
 // 
 // ===================================================================

   var pi = Math.PI;
   var secsize = 4;       // round second display to
   var distsize = 1;      // round distance display to
   var bearsize = 1;      // round bearing display to
   var tol = 0.000000000000001;

function about(){

var w = window.open("", "aboutwin", 'toolbar=0,location=1,directories=0,status=1,menubar=0,scrollbars=1,resizable=1,width=600,height=500');
var d = w.document;
d.open();
d.writeln("<HTML>\n<HEAD>\n<TITLE>About the Rennerian Coordinate Calculator</TITLE>");
d.writeln("</HEAD>\n\n<BODY>");
d.writeln("<CENTER><H3>About the Rennerian Coordinate Calculator</H3></CENTER>");
d.writeln("<P>The HBD collective thanks <a href='http://www.gazza.co.nz/'>Gary Nicholson</A> for allowing modification to his original code for HBD cameraderie.  Brian Levetzow.");
d.writeln("<P>The lat/lon coordinates can be entered in decimal degrees in the degree field.  The results are rounded to better fit the [0,0] coordinate 'standard'.");
d.writeln("<P><HR><P>Thanks to <a href='http://www.best.com/~williams/'>Ed Williams</A> for the original formulae used here. The user accepts sole responsibility for the use and results of this calculator.");
d.writeln("<P>The convention I use on all my calculators is Positive for East and North, Negative for South and West.");
d.writeln("<P>If you find any errors or have any suggestions to make about this calculator <a href='mailto:nicholsongary@hotmail.com'>send me an email</a>.<P>");
d.writeln("<P><H6><A href='http://www.gazza.co.nz/'>Gary Nicholson</A>, 10 June 2001.</H6>");
d.writeln("<P><FORM>\n<CENTER>\n<INPUT TYPE=button VALUE=' Close About ' onClick='window.close()'>\n</CENTER>\n</FORM>");
d.writeln("</BODY>\n</HTML>");
d.close();
return true;
}

function huh(){

var w = window.open("", "aboutwin", 'toolbar=0,location=1,directories=0,status=1,menubar=0,scrollbars=1,resizable=1,width=600,height=500');
var d = w.document;
d.open();
d.writeln("<HTML>\n<HEAD><TITLE>What are my Geo-coordinates?</TITLE>");
d.writeln("</HEAD><BODY>");
d.writeln("<CENTER><H3>What are my Geo-coordinates?</H3></CENTER>");
d.writeln("<P>Here are just a few ways for you to generate your Geographic coordinates:");
d.writeln("<P>--Use a GPS receiver (O.K., THAT was obvious)");
d.writeln("<P>--Go to <A href='http://maps.yahoo.com' target=new>Yahoo Maps</A> and map your address.  Then zoom into the highest magnification.");
d.writeln("Your Geo-coordinates will appear in the URL line in decimal degree form.  The info you're looking for will look like this:");
d.writeln("<P><B> Yahoo format = &slt=39.132400&sln=-76.840800</B>");
d.writeln("<BR><P>--Go to the <A href='http://www.census.gov/cgi-bin/gazetteer' target=new>Census Bureau Gazetteer</A> and use your ZIP code as a starting point.  You can then browse the Tiger Map, refine your location, and your coordinates will appear below the Tiger Map.");
d.writeln("<P>You can enter any of these decimal numbers directly into the latitude and longitude Degree fields (minutes and seconds not needed if using the decimal format).  ");
d.writeln("<P>--Please share other ideas by posting in HBD.");
d.writeln("<FORM><CENTER><INPUT TYPE=button VALUE=' Close About ' onClick='window.close()'></CENTER></FORM>");
d.writeln("</BODY></HTML>");
d.close();
return true;
}

function deg2rad(x){                //convert decimal degrees to radians
  x = x * pi / 180;
  return x;
}

function rad2deg(x){                //convert radians to decimal degrees
  x = x * 180 / pi;
  return x;
}

function roundoff(x,y){              //round off x to y decimal places
  x = parseFloat(x);
  y = parseFloat(y);
  x = Math.round(x * Math.pow(10,y))/Math.pow(10,y);
  return x;
}

function mod(x,y){           
  return x-y*Math.floor(x/y);
}

function modlon(x){         //ensure longitude is +/-180
  return mod(x+pi,2*pi)-pi;
}

function modcrs(x){        //ensure course is 0-360
  return mod(x,2*pi);
}

function modlat(x){         //ensure latitude is +/-90
  return mod(x+pi/2,2*pi)-pi/2;
}

function dms2ddd(d,m,s){

  if (isblank(d)) d = '0';
   else {
      var y = d.slice(0, 1);
      d = parseFloat(d);
   }
  if (isblank(m)) m = '0';
   else
      m = parseFloat(m);
  if (isblank(s)) s = '0';
   else
      s = parseFloat(s); 
  var x = Math.abs(d) + (Math.abs(m) / 60) + (Math.abs(s) / 3600);  //convert to decimal degrees
  if ((y == "-") || (d < 0) || (m < 0) || (s < 0)) x = -x;
  return x;

}

function isblank(s)
{
  for(var i = 0; i < s.length; i++) {
      var c = s.charAt(i);
      if ((c != ' ') && (c != '\n') && (c != '\t')) return false;
  }
  return true;
}

//function calcRandBgc(form, in1, in2, in3, in4, in5, in6){     //calculate great circle distance and course
function calcRandBgc(form, in1, in2, in3, in4, in5){     //calculate great circle distance and course
  // in1 - point 1 latitude index
  // in2 - point 1 longitude index
  // in3 - point 2 latitude index 
  // in4 - point 2 longitude index
  // in5 - distance index
  // in6 - bearing index

var j = form.units.selectedIndex;
var units = form.units.options[j].value;

  var latddd1 = dms2ddd(form.degreevalue[in1].value, form.minutevalue[in1].value, form.secondvalue[in1].value);  // convert latitude of point to decimal degrees then radians
  var latrad1 = deg2rad(latddd1);
  var londdd1 = dms2ddd(form.degreevalue[in2].value, form.minutevalue[in2].value, form.secondvalue[in2].value);  // likewise for longitude
  var lonrad1 = deg2rad(londdd1);
  var latddd2 = dms2ddd(form.degreevalue[in3].value, form.minutevalue[in3].value, form.secondvalue[in3].value);  // convert latitude of point to decimal degrees then radians
  var latrad2 = deg2rad(latddd2);
  var londdd2 = dms2ddd(form.degreevalue[in4].value, form.minutevalue[in4].value, form.secondvalue[in4].value);  // likewise for longitude
  var lonrad2 = deg2rad(londdd2);

  var w = lonrad2 - lonrad1; 
  var v = latrad1 - latrad2;
  var s = 2 * Math.asin(Math.sqrt((Math.sin(v / 2) * Math.sin(v / 2)) + (Math.cos(latrad1) * Math.cos(latrad2) * Math.sin(w / 2) * Math.sin(w / 2))));
 

if (Math.cos(latrad1) < tol){      //initial point is pole
   if (latrad1 > 0){         //start from north pole 
  var  x = pi;
        }  
   else {                    //start from south pole
  var  x = 0;
        }
    }
else {                                 //initial point isn't on pole
   if (Math.sin(lonrad1 - lonrad2) < 0){
      var x = Math.acos((Math.sin(latrad2) - Math.sin(latrad1) * Math.cos(s)) / (Math.sin(s) * Math.cos(latrad1)));
    }
   else {
      var x = 2 * pi - Math.acos((Math.sin(latrad2) - Math.sin(latrad1) * Math.cos(s)) / (Math.sin(s) * Math.cos(latrad1)));
    }
}      
      
  s = (s * 180 * 60 * 1852) / pi;   // answer in metres
  form.distvalue.value = roundoff((s / units), distsize);  //round off distance and convert to selected units
  
if (w == 0) {
   if (latddd2 < latddd1) 
       x =  pi;
   else if (latddd2 > latddd1) 
       x = 0;
   else if (latddd2 == latddd1) {
       x = 0;
       form.distvalue.value = roundoff(0, distsize);  //round off distance
   }
}

  var bearing = rad2deg(x);
  bearing = roundoff(bearing,bearsize);
  form.distvalue.value = "[" + form.distvalue.value + ", " + bearing +"deg] AR";

return true;
}

function dddround(form, ind, bearing){
  
  var y = Math.abs(parseFloat(bearing));
  y = roundoff(y,bearsize);              // round off decimal bearing
  form.degreevalue[ind].value = y;
  form.degreevalue[ind].value += "\260"; // add the degree sign to the end

return true;
}
