var R2D = 180.0 / Math.PI;
var D2R = Math.PI / 180.0;
function Degrees2Radians(deg)
{
	return (D2R * deg);
}
function Radians2Degrees(rad)
{
	return (R2D * rad);
}
function alpha(lat,e_sq,e)
{
	var sin = Math.sin(lat);
	var sinsq = Math.pow(sin,2);
	return (1 - e_sq) * (((sin / (1 - e_sq * sinsq)) - 1/(2 * e) * Math.log((1 - e * sin) / (1 + e * sin))));
}
function Ro(a,semimajor,C,n)
{
	return semimajor * Math.sqrt((C - n * a)) / n;
}
function Coordinate(x,y)
{
	this.x = x;
	this.y = y;
}
Coordinate.prototype.toString = function()
{
	return "(" +this.x+ ","+this.y+")";
}
var inchesPerUnit = new Array(1, 12,63360.0,39.3701,39370.1,4374754);
function Unit(){}	// per pix
Unit.PIX = 0;		//1 
Unit.FEET = 1;		//12
Unit.MILE = 2;		//63360.0
Unit.METER = 3;		//39.3701
Unit.LILOMETER = 4;	//39370.1
Unit.DEGREE = 5;	//4374754

function AlbersProjection(semimajor,semiminor,centralmeridian,latitudeoforigin,standardparallel1,standardparallel2,falseeasting,falsenorthing)
{
	this.name = "Albers";	
	this.SRS = "EPSG:****";
	this.unit = Unit.METER;
	this._e = 0.0;
	this._es = 0.0;
	this.C=0.0;		//constant c 
	this.e=0.0;		//eccentricity
	this.e_sq = 0.0;
	this.ro0=0.0;
	this.n=0.0;	
	//Projection parameters 
	this.lon_center = Degrees2Radians(centralmeridian)//central_meridian;
	var lat0 = Degrees2Radians(latitudeoforigin)//latitude_of_origin;
	var lat1 = Degrees2Radians(standardparallel1)//standard_parallel_1;
	var lat2 = Degrees2Radians(standardparallel2)//standard_parallel_2;
	this._falseEasting 	= Degrees2Radians(falseeasting)//false_easting;
	this._falseNorthing = Degrees2Radians(falsenorthing)//false_northing;
	this._semiMajor = semimajor;
	this._semiMinor = semiminor;
	//Ellipsoid
	this._es = 1.0 - (this._semiMinor * this._semiMinor ) / ( this._semiMajor * this._semiMajor);
	this._e  = Math.sqrt(this._es);		
	this.e_sq = 1.0 - Math.pow(this._semiMinor / this._semiMajor, 2);
	this.e = Math.sqrt(this.e_sq); //Eccentricity

	var alpha1 = alpha(lat1,this.e_sq,this.e);
	var alpha2 = alpha(lat2,this.e_sq,this.e);
	var m1 = Math.cos(lat1) / Math.sqrt(1 - this.e_sq * Math.pow(Math.sin(lat1), 2));
	var m2 = Math.cos(lat2) / Math.sqrt(1 - this.e_sq * Math.pow(Math.sin(lat2), 2));
	this.n = (Math.pow(m1, 2) - Math.pow(m2, 2)) / (alpha2 - alpha1);
	this.C = Math.pow(m1, 2) + (this.n * alpha1);
	this.ro0 = Ro(alpha(lat0,this.e_sq,this.e),this._semiMajor,this.C,this.n);
}
AlbersProjection.prototype.Forward = function(gX,gY)
{
	var dlon = Degrees2Radians(gX);
	var dlat = Degrees2Radians(gY);	
	var a = alpha(dlat,this.e_sq,this.e);
	var ro = Ro(a,this._semiMajor,this.C,this.n);
	var theta = this.n * (dlon - this.lon_center);
	return new Coordinate(this._falseEasting + ro * Math.sin(theta),this._falseNorthing + this.ro0 - (ro * Math.cos(theta)));
}
var tsman='';
AlbersProjection.prototype.betweenGPS=function(x0,y0,x1,y1){
	var xp=this.Forward(x0,y0);
	x0=xp.x;
	y0=xp.y;
	tsman+="\n"+xp;
	xp=this.Forward(x1,y1);
	x1=xp.x;
	y1=xp.y;
	tsman+="\n"+xp;
	var x=(x1-x0)*(x1-x0);
    var y=(y1-y0)*(y1-y0);
    var len=Math.pow(x+y,1/2);
	tsman+="\n"+len;
    return len;
}
AlbersProjection.prototype.betweenMAP=function(x0,y0,x1,y1){
	var xy=this.toGPS(x0,y0);
	tsman+="\n"+xy;
	var xy1=this.toGPS(x1,y1);
	tsman+="\n"+xy1;
	return this.betweenGPS(xy[0],xy[1],xy1[0],xy1[1]);
}
AlbersProjection.prototype.toGPS=function(x0,y0){
	x0=113.534+x0/1000;
	y0=34.836-y0/1000;
	return [x0,y0];
}
AlbersProjection.prototype.mapToXY=function(x,y){
	var xy=this.toGPS(x,y);
	return this.Forward(xy[0],xy[1]);
}
AlbersProjection.prototype.gpsToXY=function(x,y){
	var xy=this.Forward(x,y);
	return xy;
}
var tsmGPS=new AlbersProjection(6378137,6356752.3142,105,0,25,47,0,0);
tsmGPS.betweenMAP(141.875,71.15,126.4375,82.45)