﻿
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
/* Albers投影
   地球椭球参数
       长轴：semimajor
       短轴：semiminor       
   投影参数
       中央经线：centralmeridian
       中央纬线：latitudeoforigin
       第一纬线：standardparallel1
       第二纬线：standardparallel2
       向东偏移：falseeasting
       向北偏移：falsenorthing
*/
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)
{//经纬度到xy坐标变换
	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)));
}
AlbersProjection.prototype.Inverse = function(pX,pY) 
{//xy坐标到经纬度变换
	var theta = Math.atan((pX - this._falseEasting) / (this.ro0 - (pY - this._falseNorthing)));
	var ro = Math.sqrt(Math.pow(pX - this._falseEasting, 2) + Math.pow(this.ro0 - (pY - this._falseNorthing), 2));
	var q = (this.C - Math.pow(ro, 2) * Math.pow(this.n, 2) / Math.pow(this._semiMajor, 2)) / this.n;
	var b = Math.sin(q / (1 - ((1 - this.e_sq) / (2 * this.e)) * Math.log((1 - this.e) / (1 + this.e))));
	
	var lat = Math.asin(q * 0.5);
	var preLat = Number.MAX_VALUE;
	var iterationCounter = 0;
	while (Math.abs(lat - preLat) > 0.000001)
	{
		preLat = lat;
		var sin = Math.sin(lat);	
		var e2sin2 = this.e_sq * Math.pow(sin, 2);
		lat += (Math.pow(1 - e2sin2, 2) / (2 * Math.cos(lat))) * ((q / (1 - this.e_sq)) - sin / (1 - e2sin2) + 1 / (2 * this.e) * Math.log((1 - this.e * sin) / (1 + this.e * sin)));
		iterationCounter++;
		if (iterationCounter > 25)
		{
			return null;
		}
	}
	var lon = this.lon_center + (theta / this.n);
	return  new Coordinate(Radians2Degrees(lon), Radians2Degrees(lat));	
}
/* Albers中国地图投影
   地球椭球参数（WGS84）：
       长轴(semiMajor)：6378137;
       短轴(semiMinor)：6356752.3142;
       扁率(Flattening)：298.257223563
   投影参数
       中央经线(central_meridian)：105.0
       中央纬线(latitude_of_origin)：0.0
       第一纬线(standard_parallel_1)：25
       第二纬线(standard_parallel_1)：47
       向东偏移(falseEasting)：0
       向北偏移(falseNorthing)：0
*/
function ChinaAlbersProjection()
{
	//中国Albers投影 定义相关的参数
	this.init = true;
	AlbersProjection.apply(this,[6378137,6356752.3142,105,0,25,47,0,0]);
	this.name = 'Albers'; 
	this.SRS = "EPSG:****";
	for (var p in AlbersProjection.prototype)
    {
        if (!ChinaAlbersProjection.prototype[p])
        {
            ChinaAlbersProjection.prototype[p]= AlbersProjection.prototype[p];
        }
    }   
}

function WGS84()
{
	this.name="WGS84";
	this.SRS = "EPSG:4326";
	this.unit = Unit.DEGREE;
}
WGS84.prototype.Forward = function(gX,gY)
{
	return new Coordinate(gX,gY);
}
WGS84.prototype.Inverse = function(pX,pY)
{
	return new Coordinate(pX,pY);
}

function LocalPrj()
{
	this.name="WGS84";
	this.SRS = "EPSG:";
	this.unit = Unit.METER;
}
LocalPrj.prototype.Forward = function(gX,gY)
{
	return new Coordinate(gX,gY);
}
LocalPrj.prototype.Inverse = function(pX,pY)
{
	return new Coordinate(pX,pY);
}