function ComputeDistance(point1, point2){
    //get select  values
var signlat1,signlat2,signlon1,signlon2,dc
var lat1,lat2,lon1,lon2
var d,crs12,crs21
var argacos
var a,invf
  /* Input and validate data */
signlat1=signlatlon(point1['lat'])
signlat2=signlatlon(point2['lat'])
signlon1=signlatlon(point1['lon'])
signlon2=signlatlon(point2['lon'])


lat1=(Math.PI/180)*signlat1*point1['lat']
lat2=(Math.PI/180)*point2['lat']
lon1=(Math.PI/180)*point1['lon']
lon2=(Math.PI/180)*point2['lon']

//alert("lat1=" + lat1 + "lon1=" + lon1 +"\nlat2=" +lat2+ "lon2="+lon2)

dc=dconv('nm') /* get distance conversion factor */
//alert("dc=" +dc)

ellipse=getEllipsoid("WGS84") //get ellipse
//showProps(ellipse,"ellipse")

if (ellipse.name=="Sphere"){
  // spherical code
  cd=crsdist(lat1,lon1,lat2,lon2) // compute crs and distance
  crs12 =cd.crs12*(180/Math.PI)
  crs21 =cd.crs21*(180/Math.PI)
  d=cd.d*(180/Math.PI)*60*dc  // go to physical units
} else {
  // elliptic code
  cde=crsdist_ell(lat1,-lon1,lat2,-lon2,ellipse)  // ellipse uses East negative
  crs12 =cde.crs12*(180/Math.PI)
  crs21 =cde.crs21*(180/Math.PI)
  d=cde.d*dc  // go to physical units
}

//alert("d="+d+"  crs12="+crs12+"   crs21="+crs21)
	return d;
}



function signlatlon(value){
	var sign
	/*
	if (selection.selectedIndex==0){
	   sign=1
	}else{
	   sign=-1
	}
	*/

	if (value < 0) {
		sign = -1;
	} else {
		sign = 1;
	}

	return sign;
}

function dconv(unit){
   dc= [];
   dc['nm']=1.
   dc['km']=1.852 //km
   dc['sm']=185200.0/160934.40 // 1.150779448 sm
   dc['ft']=185200.0/30.48 // 6076.11549  //ft
   return dc[unit]
}

function getEllipsoid(selection){
  ells= []
  ells["Sphere"]= new ellipsoid("Sphere", 180*60/Math.PI,"Infinite") // first one
  ells["WGS84"]= new ellipsoid("WGS84",6378.137/1.852,298.257223563)
  ells["NAD27"]= new ellipsoid("NAD27",6378.2064/1.852,294.9786982138)
  ells["International"]= new ellipsoid("International",6378.388/1.852,297.0)
  ells["Krasovsky"]= new ellipsoid("Krasovsky",6378.245/1.852,298.3)
  ells["Bessel"]= new ellipsoid("Bessel",6377.397155/1.852,299.1528)
  ells["WGS72"]= new ellipsoid("WGS72",6378.135/1.852,298.26)
  ells["WGS66"]= new ellipsoid("WGS66",6378.145/1.852,298.25)
  ells["FAI sphere"]= new ellipsoid("FAI sphere",6371.0/1.852,1000000000.)

  return ells[selection]
}

function ellipsoid(name, a, invf){
  /* constructor */
  this.name=name
  this.a=a
  this.invf=invf
}

function crsdist_ell(glat1,glon1,glat2,glon2,ellipse){
// glat1 initial geodetic latitude in radians N positive
// glon1 initial geodetic longitude in radians E positive
// glat2 final geodetic latitude in radians N positive
// glon2 final geodetic longitude in radians E positive
a=ellipse.a
f=1/ellipse.invf
//alert("a="+a+" f="+f)
var r, tu1, tu2, cu1, su1, cu2, s1, b1, f1
var x, sx, cx, sy, cy,y, sa, c2a, cz, e, c, d
var EPS= 0.00000000005
var faz, baz, s
var iter=1
var MAXITER=100
  if ((glat1+glat2==0.) && (Math.abs(glon1-glon2)==Math.PI)){
    alert("Course and distance between antipodal points is undefined")
    glat1=glat1+0.00001 // allow algorithm to complete
    }
  if (glat1==glat2 && (glon1==glon2 || Math.abs(Math.abs(glon1-glon2)-2*Math.PI) <  EPS)){
    alert("Points 1 and 2 are identical- course undefined")
    out=[];
    out.d=0
    out.crs12=0
    out.crs21=Math.PI
    return out
  }
  r = 1 - f
  tu1 = r * Math.tan (glat1)
  tu2 = r * Math.tan (glat2)
  cu1 = 1. / Math.sqrt (1. + tu1 * tu1)
  su1 = cu1 * tu1
  cu2 = 1. / Math.sqrt (1. + tu2 * tu2)
  s1 = cu1 * cu2
  b1 = s1 * tu2
  f1 = b1 * tu1
  x = glon2 - glon1
  d = x + 1 // force one pass
  while ((Math.abs(d - x) > EPS) && (iter < MAXITER))
    {
      iter=iter+1
      sx = Math.sin (x)
//       alert("sx="+sx)
      cx = Math.cos (x)
      tu1 = cu2 * sx
      tu2 = b1 - su1 * cu2 * cx
      sy = Math.sqrt(tu1 * tu1 + tu2 * tu2)
      cy = s1 * cx + f1
      y = Math.atan2 (sy, cy)
      sa = s1 * sx / sy
      c2a = 1 - sa * sa
      cz = f1 + f1
      if (c2a > 0.)
	cz = cy - cz / c2a
      e = cz * cz * 2. - 1.
      c = ((-3. * c2a + 4.) * f + 4.) * c2a * f / 16.
      d = x
      x = ((e * cy * c + cz) * sy * c + y) * sa
      x = (1. - c) * x * f + glon2 - glon1
    }
  faz = modcrs(Math.atan2(tu1, tu2))
  baz = modcrs(Math.atan2(cu1 * sx, b1 * cx - su1 * cu2) + Math.PI)
  x = Math.sqrt ((1 / (r * r) - 1) * c2a + 1)
  x +=1
  x = (x - 2.) / x
  c = 1. - x
  c = (x * x / 4. + 1.) / c
  d = (0.375 * x * x - 1.) * x
  x = e * cy
  s = ((((sy*sy*4.-3.)*(1.-e-e)*cz*d/6.-x)*d/4.+cz)*sy*d+y)*c*a*r
  out=[];
  out.d=s
  out.crs12=faz
  out.crs21=baz
  if (Math.abs(iter-MAXITER)<EPS){
    alert("Algorithm did not converge")
  }
  return out

}

function crsdist(lat1,lon1,lat2,lon2){ // radian args
/* compute course and distance (spherical) */

if ((lat1+lat2==0.) && (Math.abs(lon1-lon2)==Math.PI)
                    && (Math.abs(lat1) != (Math.PI/180)*90.)){
    alert("Course between antipodal points is undefined")
    }

with (Math){

  d=acos(sin(lat1)*sin(lat2)+cos(lat1)*cos(lat2)*cos(lon1-lon2))

  if ((d==0.) || (lat1==-(PI/180)*90.)){
     crs12=2*PI
  } else if (lat1==(PI/180)*90.){
     crs12=PI
  } else {
     argacos=(sin(lat2)-sin(lat1)*cos(d))/(sin(d)*cos(lat1))
     if (sin(lon2-lon1) < 0){
       crs12=acosf(argacos)
     }
     else{
       crs12=2*PI-acosf(argacos)
     }
  }
  if ((d==0.) || (lat2==-(PI/180)*90.)){
     crs21=0.
  } else if (lat2==(PI/180)*90.){
     crs21=PI
  }else{
     argacos=(sin(lat1)-sin(lat2)*cos(d))/(sin(d)*cos(lat2))
     if (sin(lon1-lon2)<0){
       crs21=acosf(argacos)
     }
     else{
       crs21=2*PI-acosf(argacos)
     }
  }
}
out= [];
out.d=d
out.crs12=crs12
out.crs21=crs21
return out
}

function mod(x,y){
  return x-y*Math.floor(x/y)
}

function modlon(x){
  return mod(x+Math.PI,2*Math.PI)-Math.PI
}

function modcrs(x){
  return mod(x,2*Math.PI)
}

function modlat(x){
  return mod(x+Math.PI/2,2*Math.PI)-Math.PI/2
}