Пример #1
0
// Polyconic inverse equations--mapping x,y to lat/long
long Projectoid::polyinv(
double x,						// (O) X projection coordinate
double y,						// (O) Y projection coordinate
double *lon,					// (I) Longitude
double *lat)					// (I) Latitude
{
double al;			// temporary values
double b;			// temporary values
double c;			// temporary values
double t;			// <<<F2 OPT>>>
long iflg;			// error flag

// Inverse equations
x -= false_easting;
y -= false_northing;
al = ml0 + y / r_major;
iflg = 0;
t = x / r_major;
if (fabs(al) <= .0000001)
	{
	*lon = t + lon_center;
	*lat = 0.0;
	}
else
	{
	b = al * al + t * t;
	iflg = phi4z(es, e0, e1, e2, e3, al, b, &c, lat);
	if (iflg != OK)
		return(iflg);
	*lon = adjust_lon((asinz(t * c) / sin(*lat)) + lon_center);
	}

return(OK);

}
Пример #2
0
/* Van Der Grinten forward equations--mapping lat,long to x,y
  ---------------------------------------------------------*/
long vandgfor
(
    double lon,			/* (I) Longitude */
    double lat,			/* (I) Latitude */
    double *x,			/* (O) X projection coordinate */
    double *y			/* (O) Y projection coordinate */
)

{
    double dlon;
    double theta;
    double al,asq;
    double g,gsq;
    double m,msq;
    double con;
    double costh,sinth;

    /* Forward equations
      -----------------*/
    dlon = adjust_lon(lon  - lon_center);

    if (fabs(lat) <= EPSLN)
    {
        *x = false_easting  + R * dlon;
        *y = false_northing;
        return (GCTP_OK);
    }
    theta = asinz(2.0 * fabs(lat / PI));
    if ((fabs(dlon) <= EPSLN) || (fabs(fabs(lat) - HALF_PI) <= EPSLN))
    {
        *x = false_easting;
        if (lat >= 0)
            *y = false_northing + PI * R * tan(.5 * theta);
        else
            *y = false_northing + PI * R * -tan(.5 * theta);
        return(GCTP_OK);
    }
    al = .5 * fabs((PI / dlon) - (dlon / PI));
    asq = al * al;
    gctp_sincos(theta,&sinth,&costh);
    g = costh / (sinth + costh - 1.0);
    gsq = g * g;
    m = g * (2.0 / sinth - 1.0);
    msq = m * m;
    con = PI * R * (al * (g - msq) + sqrt(asq * (g - msq) * (g - msq) - (msq + asq)
                                          * (gsq - msq))) / (msq + asq);
    if (dlon < 0)
        con = -con;
    *x = false_easting + con;
    con = fabs(con / (PI * R));
    if (lat >= 0)
        *y = false_northing + PI * R * sqrt(1.0 - con * con - 2.0 * al * con);
    else
        *y = false_northing - PI * R * sqrt(1.0 - con * con - 2.0 * al * con);

    return(GCTP_OK);
}
Пример #3
0
/* Azimuthal inverse equations--mapping x,y to lat/long
  ---------------------------------------------------*/
long aziminv
(
    double x,			/* (O) X projection coordinate 	*/
    double y,			/* (O) Y projection coordinate 	*/
    double *lon,			/* (I) Longitude 		*/
    double *lat			/* (I) Latitude 		*/
)
{
double rh;		/* height above ellipsoid			*/
double z;		/* angle					*/
double sinz,cosz;	/* sin of z and cos of z			*/
double con;

/* Inverse equations
  -----------------*/
x -= false_easting;
y -= false_northing;
rh = sqrt(x * x + y * y);
if (rh > (2.0 * HALF_PI * r_major))
   {
   GCTP_PRINT_ERROR("Input data error");
   return(125);
   }
z = rh / r_major;
sincos(z,&sinz,&cosz);
*lon = lon_center;
if (fabs(rh) <= EPSLN)
   {
   *lat = lat_origin;
   return(OK);
   }
*lat = asinz(cosz * sin_p12 + (y * sinz * cos_p12) / rh);
con = fabs(lat_origin) - HALF_PI;
if (fabs(con) <= EPSLN)
   {
   if (lat_origin >= 0.0)
      {
      *lon = adjust_lon(lon_center + atan2(x , -y));
      return(OK);
      }
   else
      {
      *lon = adjust_lon(lon_center - atan2(-x , y));
      return(OK);
      }
   }
con = cosz - sin_p12 * sin(*lat);
if ((fabs(con) < EPSLN) && (fabs(x) < EPSLN))
   return(OK);
*lon = adjust_lon(lon_center + atan2((x * sinz * cos_p12), (con * rh)));

return(OK);
} 
Пример #4
0
// Wagner VII inverse equations--mapping x,y to lat,long 
long Projectoid::wviiinv(
double x,               // (I) X projection coordinate
double y,               // (I) Y projection coordinate
double *lon,            // (O) Longitude
double *lat)            // (O) Latitude
{
double t1, t2, p, c;

// Inverse equations
x -= false_easting;
y -= false_northing;
t1 = x * (1.0 / 2.66723);	// <<<F2 OPT>>>
t2 = y * (1.0 / 1.24104);	// <<<F2 OPT>>>
t1 *= t1;
t2 *= t2;
p = sqrt(t1 + t2);
c = 2.0 * asinz(p / (2.0 * R));
*lat = asinz(y * sin(c) / (1.24104 * 0.90631 * p));
*lon = adjust_lon(lon_center + 3.0 * atan2(x * tan(c), 2.66723 * p));

return(OK);

}
Пример #5
0
/* Wagner VII inverse equations--mapping x,y to lat,long 
  -----------------------------------------------------*/
long wviiinv
(
    double x,		/* (I) X projection coordinate */
    double y,		/* (I) Y projection coordinate */
    double *lon,		/* (O) Longitude */
    double *lat		/* (O) Latitude */
)
{
double t1, t2, p, c;

/* Inverse equations
  -----------------*/
x -= false_easting;
y -= false_northing;
t1 = x / 2.66723;
t2 = y / 1.24104;
t1 *= t1;
t2 *= t2;
p = sqrt(t1 + t2);
c = 2.0 * asinz(p / (2.0 * R));
*lat = asinz(y * sin(c) / (1.24104 * 0.90631 * p));
*lon = adjust_lon(lon_center + 3.0 * atan2(x * tan(c), 2.66723 * p));
return(OK);
}
Пример #6
0
/* HAMMER inverse equations--mapping x,y to lat/long
  ------------------------------------------------*/
int haminv(
double x,			/* (O) X projection coordinate */
double y,			/* (O) Y projection coordinate */
double *lon,			/* (I) Longitude */
double *lat)			/* (I) Latitude */

{
double fac;

/* Inverse equations
  -----------------*/
x -= false_easting;
y -= false_northing;
fac = sqrt(4.0 * R * R - (x * x)/ 4.0 - y * y) / 2.0;
*lon = adjust_lon(lon_center + 2.0 * 
                  atan2((x * fac), (2.0 * R * R - x * x/4 - y * y)));
*lat = asinz(y * fac / R / R);
return(OK);
}
Пример #7
0
double Util::phi1z ( double eccent,	/* Eccentricity angle in radians		*/
					  double qs,		/* Angle in radians				*/
			          long  *flag )	/* Error flag number				*/
{

	double eccnts;
	double dphi;
	double con;
	double com;
	double sinpi;
	double cospi;
	double phi;
	long i;

	phi = asinz(.5 * qs);

	if (eccent < EPSLN) 
		return(phi);
	
	eccnts = eccent * eccent;

	for (i = 1; i <= 25; i++) 
	{
		Util::gctp_sincos(phi,&sinpi,&cospi);
		con = eccent * sinpi; 
		com = 1.0 - con * con;
		dphi = .5 * com * com / cospi * (qs / (1.0 - eccnts) - sinpi / com + 
			   .5 / eccent * log ((1.0 - con) / (1.0 + con)));
		phi = phi + dphi;
		
		if (fabs(dphi) <= 1e-7)
			return(phi);
	}
	// p_error ("Convergence error","phi1z-conv");
	*flag = 001;
	return(ERROR);
}
Пример #8
0
/* ALASKA CONFORMAL inverse equations--mapping x,y to lat/long
  ----------------------------------------------------------*/
long alconinv
(
    double x,			/* (O) X projection coordinate */
    double y,			/* (O) Y projection coordinate */
    double *lon,			/* (I) Longitude */
    double *lat			/* (I) Latitude */
)

{
double esphi;
double r;
double s;
double br;
double bi;
double ai;
double ar;
double ci;
double cr;
double di;
double dr;
double arn = 0.0;
double ain = 0.0;
double crn;
double cin;
double fxyr;
double fxyi;
double fpxyr;
double fpxyi;
double xp,yp;
double den;
double dxp;
double dyp;
double ds;
double z;
double cosz;
double sinz;
double rh;
double chi;
double dphi;
double phi;
long j;
long nn;

/* Inverse equations
  -----------------*/
x = (x - false_easting) / r_major;
y = (y - false_northing) / r_major;
xp = x;
yp = y;
nn = 0;

/* Use Knuth algorithm for summing complex terms, to convert Modified-
   Stereographic conformal to Oblique Stereographic coordinates.
--------------------------------------------------------------------*/
do
  {
  r = xp + xp;
  s = xp * xp + yp * yp;
  ar = acoef[n];
  ai = bcoef[n];
  br = acoef[n -1];
  bi = bcoef[n - 1];
  cr = (double) (n) * ar;
  ci = (double) (n) * ai;
  dr = (double) (n -1) * br;
  di = (double) (n -1) * bi;

  for (j = 2; j <= n; j++)
      {
      arn = br + r * ar;
      ain = bi + r * ai;
      if (j < n)
        {
        br = acoef[n -j] - s * ar;
        bi = bcoef[n - j] - s * ai;
        ar = arn;
        ai = ain;
        crn = dr  + r * cr;
        cin = di  + r * ci;
        dr = (double) (n - j) * acoef[n -j] - s * cr;
        di = (double) (n - j) * bcoef[n -j] - s * ci;
        cr = crn;
        ci = cin;
        }
      }
  br = -s * ar;
  bi = -s * ai;
  ar = arn;
  ai = ain;
  fxyr = xp * ar - yp * ai + br - x;
  fxyi = yp * ar + xp * ai + bi - y;
  fpxyr = xp * cr - yp * ci + dr;
  fpxyi = yp * cr + xp * ci + ci;
  den = fpxyr * fpxyr + fpxyi * fpxyi;
  dxp = -(fxyr * fpxyr + fxyi * fpxyi) / den;
  dyp = -(fxyi * fpxyr - fxyr * fpxyi) / den;
  xp = xp + dxp;
  yp = yp + dyp;
  ds = fabs(dxp) + fabs(dyp);
  nn++;
  if (nn > 20)
     {
     p_error("Too many iterations in inverse","alcon-inv");
     return(235);
     }
  }
while (ds > EPSLN);

/* convert Oblique Stereographic coordinates to LAT/LONG
------------------------------------------------------*/
rh = sqrt(xp * xp + yp * yp);
z = 2.0 * atan(rh / 2.0);
gctp_sincos(z,&sinz,&cosz);
*lon = lon_center;
if (fabs(rh) <= EPSLN)
   {
   *lat = lat_center;
   return(GCTP_OK);
   }
chi = asinz(cosz * sin_p26 + (yp * sinz * cos_p26) / rh);
nn = 0;
phi = chi;
do
  {
  esphi = e * sin(phi);
  dphi = 2.0 * atan(tan((HALF_PI + chi) / 2.0) * 
         pow(((1.0 + esphi) / (1.0 - esphi)),(e / 2.0))) - HALF_PI - phi;
  phi += dphi;
  nn++;
  if (nn > 20)
     {
     p_error("Too many iterations in inverse","alcon-inv");
     return(236);
     }
  }
while(fabs(dphi) > EPSLN);

*lat = phi;
*lon = adjust_lon (lon_center + atan2((xp * sinz), (rh * cos_p26 * cosz - yp *
                   sin_p26 * sinz)));
     

return(GCTP_OK);
}
Пример #9
0
/*****************************************************************************
Name: inverse_transform

Purpose: Transforms UTM/TM X,Y to lat,long

Returns:
    GCTP_SUCCESS or GCTP_ERROR

*****************************************************************************/
static int inverse_transform
(
    const TRANSFORMATION *trans, /* I: transformation information */
    double x,       /* I: X projection coordinate */
    double y,       /* I: Y projection coordinate */
    double *lon,    /* O: Longitude */
    double *lat     /* O: Latitude */
)
{
    struct tm_proj *cache_ptr = (struct tm_proj *)trans->cache;
    double con,phi;                 /* temporary angles */
    double delta_phi;               /* difference between longitudes */
    long i;                         /* counter variable */
    double sin_phi, cos_phi, tan_phi;   /* sin cos and tangent values */
    double c, cs, t, ts, n, r, d, ds;   /* temporary variables */
    double f, h, g, temp;           /* temporary variables */
    long max_iter = 6;              /* maximun number of iterations */

    /* Use the spherical form if possible */
    if (cache_ptr->is_sphere)
    {
        f = exp(x / (cache_ptr->r_major * cache_ptr->scale_factor));
        g = 0.5 * (f - 1.0/f);
        temp = cache_ptr->lat_origin + y
               /(cache_ptr->r_major * cache_ptr->scale_factor);
        h = cos(temp);
        con = sqrt((1.0 - h * h)/(1.0 + g * g));
        *lat = asinz(con);
        if (temp < 0)
            *lat = -*lat;
        if ((g == 0) && (h == 0))
        {
            *lon = cache_ptr->lon_center;
            return GCTP_SUCCESS;
        }
        else
        {
            *lon = adjust_lon(atan2(g,h) + cache_ptr->lon_center);
            return GCTP_SUCCESS;
        }
    }

    /* Inverse equations */
    x = x - cache_ptr->false_easting;
    y = y - cache_ptr->false_northing;

    con = (cache_ptr->ml0 + y / cache_ptr->scale_factor) / cache_ptr->r_major;
    phi = con;
    for (i = 0; ; i++)
    {
        delta_phi = ((con + cache_ptr->e1 * sin(2.0*phi) - cache_ptr->e2
                      * sin(4.0*phi) + cache_ptr->e3 * sin(6.0*phi))
                     / cache_ptr->e0) - phi;
        phi += delta_phi;
        if (fabs(delta_phi) <= EPSLN)
            break;
        if (i >= max_iter)
        {
            GCTP_PRINT_ERROR("Latitude failed to converge in inverse "
                             "transform");
            return GCTP_ERROR;
        }
    }
    if (fabs(phi) < HALF_PI)
    {
        sincos(phi, &sin_phi, &cos_phi);
        tan_phi = tan(phi);
        c    = cache_ptr->esp * SQUARE(cos_phi);
        cs   = SQUARE(c);
        t    = SQUARE(tan_phi);
        ts   = SQUARE(t);
        con  = 1.0 - cache_ptr->es * SQUARE(sin_phi);
        n    = cache_ptr->r_major / sqrt(con);
        r    = n * (1.0 - cache_ptr->es) / con;
        d    = x / (n * cache_ptr->scale_factor);
        ds   = SQUARE(d);
        *lat = phi - (n * tan_phi * ds / r) * (0.5 - ds / 24.0 * (5.0 + 3.0
                                               * t + 10.0 * c - 4.0 * cs - 9.0 * cache_ptr->esp - ds / 30.0
                                               * (61.0 + 90.0 * t + 298.0 * c + 45.0 * ts - 252.0
                                                       * cache_ptr->esp - 3.0 * cs)));
        *lon = adjust_lon(cache_ptr->lon_center + (d * (1.0 - ds / 6.0
                          * (1.0 + 2.0 * t + c - ds / 20.0 * (5.0 - 2.0 * c + 28.0
                                  * t - 3.0 * cs + 8.0 * cache_ptr->esp + 24.0 * ts)))
                          / cos_phi));
    }
    else
    {
        *lat = HALF_PI * gctp_get_sign(y);
        *lon = cache_ptr->lon_center;
    }
    return GCTP_SUCCESS;
}
int inverse_albers_conic_equal_area_ellipsoid(mapx_class *current,
					      double x, double y, 
					      double *lat, double *lon)
{
  double phi, lam, rho, rmy, theta, q;
  double q_test;
  double cos_phi;
  double sin_phi;
  double esin_phi;
  double one_m_e2sin2_phi;
  double delta_phi;
  double one_m_e2;
  double one_over_2e;
  double epsilon = 1e-6;
  int it_max = 35;
  int i;
  
  x -= current->false_easting;
  y -= current->false_northing;

  rmy = current->rho0 - y;
  rho = sqrt( x*x + rmy*rmy );
  
  theta = current->n >= 0 ?
    atan2( x,  rmy) :
    atan2(-x, -rmy);
  lam = theta / current->n;
  
  
  q = (current->C - ( (rho*rho*current->n*current->n) /
		      (current->Rg*current->Rg) ) ) / current->n;
          
/***  Calculate phi using equation 3-16, Snyder 1987, p102 ***/
 
  q_test = 1.0 - (1.0 - current->e2)/(2.0 * current->eccentricity) *
    log((1.0 - current->eccentricity) / (1.0 + current->eccentricity));
  if (fabs(fabs(q) - fabs(q_test)) < epsilon) {
    phi = sign(q) * PI / 2;
  } else {

    phi = asinz(q / 2.0);
    one_m_e2 = 1.0 - current->e2;
    one_over_2e = 1.0 / (2.0 * current->eccentricity);
    
    for (i = 0; i < it_max; i++) {
      cos_phi = cos(phi);
      if (cos_phi < epsilon) {
	phi = sign(q) * PI / 2;
	break;
      }
      sin_phi = sin(phi);
      esin_phi = current->eccentricity * sin_phi;
      one_m_e2sin2_phi = 1.0 - esin_phi * esin_phi;
      delta_phi = one_m_e2sin2_phi * one_m_e2sin2_phi / (2.0 * cos_phi) *
	(q / one_m_e2 - sin_phi / one_m_e2sin2_phi + one_over_2e *
	 log((1.0 - esin_phi) / (1.0 + esin_phi)));
      phi += delta_phi;
      if (fabs(delta_phi) < epsilon)
	break;
    }
  }

  *lat = DEGREES(phi);
  *lon = DEGREES(lam) + current->lon0;
  NORMALIZE(*lon);
  
  return 0;
  
}
Пример #11
0
/* Initialize the General Lambert Azimuthal Equal Area projection
  --------------------------------------------------------------*/
int lamazforint(
double r_maj,			/* major axis		        	*/
double r_min,			/* minor axis		        	*/
double center_long,		/* (I) Center longitude 		*/
double center_lat,		/* (I) Center latitude 			*/
double false_east,		/* x offset in meters			*/
double false_north)		/* y offset in meters			*/
{
/* Place parameters in static storage for common use
  -------------------------------------------------*/
R = r_maj;
 if(fabs(r_min) < EPSLN ) /* sphere */
   {
     r_major = r_maj;
     r_minor = r_maj;
   }
 else /* sphere or ellipsoide */
   {
     r_major = r_maj;
     r_minor = r_min;
   }

lon_center = center_long;
lat_center = center_lat;
false_easting = false_east;
false_northing = false_north;
tsincos(center_lat, &sin_lat_o, &cos_lat_o);
sinphi1 = sin_lat_o; 
cosphi1 = cos_lat_o;

es = 1.0 - SQUARE(r_minor / r_major);
e = sqrt(es);

 if(es < 0.00001)
   {
     ind = 1; /* sphere */
     qp = 2.0;
     q1 = 2.0;
   }
 else
   {
     ind = 0; /* ellipsoid */
     qp = (1.0 - es)* (((1.0/(1.0 - es))-(1.0/(2.0*e))*log((1.0 - e)/(1.0 + e))));
     
     if((fabs (lat_center - HALF_PI) <=  EPSLN ) || (fabs (lat_center + HALF_PI) <=  EPSLN ))
       {
	 /* no other constants needed for LA with North and South polar Aspects lat_center = 90 or -90*/
       }
     else
       {
	 tsincos(lat_center, &sinphi1, &cosphi1);
	 q1 = (1.0 - es) * ((sinphi1 / (1.0 - es * sinphi1 * sinphi1))
				- (1.0 / (2.0 * e)) * 
				log((1.0 - e * sinphi1)/(1.0 + e * sinphi1)));
	 Rq = r_major * sqrt(qp/2.0);
	 if(fabs(q1) >= fabs(qp))
	   {
	     beta1 = HALF_PI * (fabs(q1/qp)/(q1/qp));
	   }
	 else
	   {
	     beta1 = asinz(q1/qp);
	   }
	 tsincos(beta1, &sin_beta1, &cos_beta1);
	 m1 = cosphi1 / sqrt(1.0 - es * sinphi1 * sinphi1);
	 D = (r_major * m1)/ (Rq * cos_beta1);
       }
   }

/* Report parameters to the user
  -----------------------------*/
ptitle("LAMBERT AZIMUTHAL EQUAL-AREA"); 
radius2(r_major, r_minor);
cenlon(center_long);
cenlat(center_lat);
offsetp(false_easting,false_northing);
return(OK);
}
Пример #12
0
/* Lambert Azimuthal Equal Area forward equations--mapping lat,long to x,y
  -----------------------------------------------------------------------*/
int lamazfor(
double lon,			/* (I) Longitude */
double lat,			/* (I) Latitude */
double *x,			/* (O) X projection coordinate */
double *y)			/* (O) Y projection coordinate */
{
double delta_lon;	/* Delta longitude (Given longitude - center 	*/
double sin_delta_lon;	/* Sine of the delta longitude 			*/
double cos_delta_lon;	/* Cosine of the delta longitude 		*/
double sinphi;	        /* Sine of the center latitude 	        	*/
double cosphi;	        /* Cosine of the center latitude        	*/
double sin_lat;		/* Sine of the given latitude 			*/
double cos_lat;		/* Cosine of the given latitude 		*/
double g;		/* temporary varialbe				*/
double ksp;		/* heigth above elipsiod			*/
char mess[60];
double qpmq, qppq, rho; 
double beta, sin_beta, cos_beta;
double q, B;

/* Forward equations
   -----------------*/
 if( ind != 0) /* sphere */
   {
     delta_lon = adjust_lon(lon - lon_center);
     tsincos(lat, &sin_lat, &cos_lat);
     tsincos(delta_lon, &sin_delta_lon, &cos_delta_lon);
     g = sin_lat_o * sin_lat + cos_lat_o * cos_lat * cos_delta_lon;
     if (g == -1.0) 
       {
	 sprintf(mess, "Point projects to a circle of radius = %lf\n", 2.0 * R);
	 p_error(mess, "lamaz-forward");
	 return(113);
       }
     ksp = R * sqrt(2.0 / (1.0 + g));
     *x = ksp * cos_lat * sin_delta_lon + false_easting;
     *y = ksp * (cos_lat_o * sin_lat - sin_lat_o * cos_lat * cos_delta_lon) + 
       false_northing;
   }
 else /* ellipsoid */
   {
     delta_lon = adjust_lon(lon - lon_center);
     tsincos(lat, &sinphi, &cosphi);
     q = (1.0 - es) * ((sinphi / (1.0 - es * sinphi * sinphi))
		       - (1.0 / (2.0 * e)) * 
		       log((1.0 - e * sinphi)/(1.0 + e * sinphi)));
     
     if (fabs(lat_center - HALF_PI) <= EPSLN)  /* if Northern Polar Aspect */
       {
	 qpmq = qp - q;
	 if (fabs(qpmq) <= EPSLN)
	   {
	     rho = 0.0;
	   }
	 else
	   {
	     rho = r_major * sqrt(qpmq);
	   }
	 *x = false_easting  + rho * sin(delta_lon);
	 *y = false_northing - rho * cos(delta_lon);
       }
     else if (fabs(lat_center + HALF_PI) <= EPSLN)  /* if Southern Polar Aspect */
       {
	 qppq = qp + q;
	 if (fabs(qppq) <= EPSLN)
	   {
	     rho = 0.0;
	   }
	 else
	   {
	     rho = r_major * sqrt(qppq);
	   }
	 *x =  false_easting  + rho * sin(delta_lon);
	 *y =  false_northing + rho * cos(delta_lon);
       }
     else /* with any other latitude of origin */
       {
	 beta = asinz(q/qp);
	 tsincos(beta, &sin_beta, &cos_beta);
	 B = Rq * sqrt((2.0/(1.0 + sin_beta1 * sin_beta + cos_beta1 * cos_beta * cos(delta_lon))));

	 *x = false_easting  + (B*D) * (cos_beta * sin(delta_lon));
	 *y = false_northing + (B/D) * (cos_beta1 * sin_beta - sin_beta1 * cos_beta * cos(delta_lon));
       }
   }

 return(OK);
}