/* Initialize the General Vertical Near-Side Perspective projection ---------------------------------------------------------------*/ long gvnspforint ( double r, /* (I) Radius of the earth (sphere) */ double h, /* height above sphere */ 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; p = 1.0 + h / R; lon_center = center_long; false_easting = false_east; false_northing = false_north; gctp_sincos(center_lat, &sin_p15, &cos_p15); /* Report parameters to the user -----------------------------*/ ptitle("GENERAL VERTICAL NEAR-SIDE PERSPECTIVE"); radius(r); genrpt(h,"Height of Point Above Surface of Sphere: "); cenlon(center_long); cenlat(center_lat); offsetp(false_easting,false_northing); return(GCTP_OK); }
long obleqforint ( double r, double center_long, double center_lat, double shape_m, double shape_n, double angle, double false_east, double false_north ) { /* Place parameters in static storage for common use -------------------------------------------------*/ R = r; lon_center = center_long; lat_o = center_lat; m = shape_m; n = shape_n; theta = angle; false_easting = false_east; false_northing = false_north; /* Report parameters to the user (to device set up prior to this call) -------------------------------------------------------------------*/ ptitle("OBLATED EQUAL-AREA"); radius(R); cenlon(lon_center); cenlat(lat_o); genrpt(m,"Parameter m: "); genrpt(n,"Parameter n: "); genrpt(theta,"Theta: "); offsetp(false_easting,false_northing); /* Calculate the sine and cosine of the latitude of the center of the map and store in static storage for common use. -------------------------------------------*/ gctp_sincos(lat_o, &sin_lat_o, &cos_lat_o); return(GCTP_OK); }
// Initialize the Universal Transverse Mercator (UTM) projection long Projectoid::utmforint( double r_maj, // major axis double r_min, // minor axis double scale_fact, // scale factor long zone) // zone number { double temp; // temporary variable if ((abs(zone) < 1) || (abs(zone) > 60)) { p_error("Illegal zone number", "utm-forint"); return(11); } r_major = r_maj; r_minor = r_min; scale_factor = scale_fact; lat_origin = 0.0; lon_center = ((6 * abs(zone)) - 183) * D2R; false_easting = 500000.0; false_northing = (zone < 0) ? 10000000.0 : 0.0; temp = r_minor / r_major; es = 1.0 - SQUARE(temp); e = sqrt(es); e0 = e0fn(es); e1 = e1fn(es); e2 = e2fn(es); e3 = e3fn(es); ml0 = r_major * mlfn(e0, e1, e2, e3, lat_origin); esp = es / (1.0 - es); if (es < .00001) ind = 1; // Report parameters to the user ptitle("UNIVERSAL TRANSVERSE MERCATOR (UTM)"); genrpt_long(zone, "Zone: "); radius2(r_major, r_minor); genrpt(scale_factor, "Scale Factor at C. Meridian: "); cenlonmer(lon_center); ForwardOK[WCS_PROJECTIONCODE_UTM] = 1; ForwardTransform = &Projectoid::utmfor; return(OK); }
/* Initialize the Universal Transverse Mercator (UTM) projection -------------------------------------------------------------*/ long utmforint ( double r_maj, /* major axis */ double r_min, /* minor axis */ double scale_fact, /* scale factor */ long zone /* zone number */ ) { double temp; /* temporary variable */ if ((abs(zone) < 1) || (abs(zone) > 60)) { p_error("Illegal zone number","utm-forint"); return(11); } r_major = r_maj; r_minor = r_min; scale_factor = scale_fact; lat_origin = 0.0; lon_center = ((6 * abs(zone)) - 183) * D2R; false_easting = 500000.0; false_northing = (zone < 0) ? 10000000.0 : 0.0; temp = r_minor / r_major; es = 1.0 - SQUARE(temp); e0 = e0fn(es); e1 = e1fn(es); e2 = e2fn(es); e3 = e3fn(es); ml0 = r_major * mlfn(e0, e1, e2, e3, lat_origin); esp = es / (1.0 - es); if (es < .00001) ind = 1; /* Report parameters to the user -----------------------------*/ ptitle("UNIVERSAL TRANSVERSE MERCATOR (UTM)"); genrpt_long(zone, "Zone: "); radius2(r_major, r_minor); genrpt(scale_factor,"Scale Factor at C. Meridian: "); cenlonmer(lon_center); return(GCTP_OK); }
long somforint( double r_major, double r_minor, long satnum, long path, double alf_in, double lon, double false_east, double false_north, double time, long start1, long flag) /*double r_major; major axis double r_minor; minor axis long satnum; Landsat satellite number (1,2,3,4,5) long path; Landsat path number double alf_in; double lon; double false_east; x offset in meters double false_north; y offset in meters double time; long start1; long flag; */ { long i; double alf,e2c,e2s,one_es; double dlam,fb,fa2,fa4,fc1,fc3,suma2,suma4,sumc1,sumc3,sumb; /* Place parameters in static storage for common use -------------------------------------------------*/ false_easting = false_east; false_northing = false_north; a = r_major; b = r_minor; es = 1.0 - SQUARE(r_minor/r_major); if (flag != 0) { alf = alf_in; p21 = time / 1440.0; lon_center = lon; start = start1; } else { if (satnum < 4) { alf = 99.092 * D2R; p21=103.2669323/1440.0; lon_center = (128.87 - (360.0/251.0 * path)) * D2R; } else { alf = 98.2 * D2R; p21=98.8841202/1440.0; lon_center = (129.30 - (360.0/233.0 * path)) * D2R; /* lon_center = (-129.30557714 - (360.0/233.0 * path)) * D2R; */ } start=0.0; } /* Report parameters to the user (to device set up prior to this call) -------------------------------------------------------------------*/ ptitle("SPACE OBLIQUE MERCATOR"); radius2(a,b); if (flag == 0) { genrpt_long(path, "Path Number: "); genrpt_long(satnum, "Satellite Number: "); } genrpt(alf*R2D, "Inclination of Orbit: "); genrpt(lon_center*R2D,"Longitude of Ascending Orbit: "); offsetp(false_easting,false_northing); genrpt(LANDSAT_RATIO, "Landsat Ratio: "); ca=cos(alf); if (fabs(ca)<1.e-9) ca=1.e-9; sa=sin(alf); e2c=es*ca*ca; e2s=es*sa*sa; w=(1.0-e2c)/(1.0-es); w=w*w-1.0; one_es=1.0-es; q = e2s / one_es; t = (e2s*(2.0-es)) / (one_es*one_es); u= e2c / one_es; xj = one_es*one_es*one_es; dlam=0.0; som_series(&fb,&fa2,&fa4,&fc1,&fc3,&dlam); suma2=fa2; suma4=fa4; sumb=fb; sumc1=fc1; sumc3=fc3; for(i=9;i<=81;i+=18) { dlam=i; som_series(&fb,&fa2,&fa4,&fc1,&fc3,&dlam); suma2=suma2+4.0*fa2; suma4=suma4+4.0*fa4; sumb=sumb+4.0*fb; sumc1=sumc1+4.0*fc1; sumc3=sumc3+4.0*fc3; } for(i=18; i<=72; i+=18) { dlam=i; som_series(&fb,&fa2,&fa4,&fc1,&fc3,&dlam); suma2=suma2+2.0*fa2; suma4=suma4+2.0*fa4; sumb=sumb+2.0*fb; sumc1=sumc1+2.0*fc1; sumc3=sumc3+2.0*fc3; } dlam=90.0; som_series(&fb,&fa2,&fa4,&fc1,&fc3,&dlam); suma2=suma2+fa2; suma4=suma4+fa4; sumb=sumb+fb; sumc1=sumc1+fc1; sumc3=sumc3+fc3; a2=suma2/30.0; a4=suma4/60.0; b=sumb/30.0; c1=sumc1/15.0; c3=sumc3/45.0; return(OK); }
/* !C****************************************************************************** !Description: Isin_for_init (initialize mapping) initializes the integerized sinusoidal transformations by calculating constants and a short-cut lookup table. !Input Parameters: sphere sphere radius (user's units) lon_cen_mer longitude of central meridian (radians) false_east easting at projection origin (user's units) false_north northing at projection origin (user's units) nrow number of rows (longitudinal zones) ijustify justify flag; flag to indicate what to do with rows with an odd number of columns; 0 = indicates the extra column is on the right of the projection y axis; 1 = indicates the extra column is on the left of the projection y axis; 2 = calculate an even number of columns !Output Parameters: (returns) a handle for this instance of the integerized sinusoidal projection or NULL for error !Team Unique Header: ! Usage Notes: 1. The sphere radius must not be smaller than 'EPS_SPHERE'. 2. The longitude must be in the range [-'TWO_PI' to 'TWO_PI']. 3. The number of rows must be a multiple of two and no more than 'NROW_MAX'. !END**************************************************************************** */ Isin_t *Isin_for_init ( double sphere, double lon_cen_mer, double false_east, double false_north, long nrow, int ijustify ) { Isin_t *this; /* 'isin' data structure */ Isin_row_t *row; /* current row data structure */ long irow; /* row (zone) index */ double clat; /* central latitude of the row */ long ncol_cen; /* number of columns in the central row of the grid (at the equator) */ #ifdef CHECK_EDGE double dcol; /* delta column (normalized by number of columns) */ double dcol_min, /* minimum delta column */ double log2_dcol_min; /* log base 2 of minimum delta column */ dcol_min = 1.0; #endif /* Check input parameters */ if ( sphere < EPS_SPHERE ) { Isin_error( &ISIN_BADPARAM, "Isin_for_init" ); return NULL; } if ( lon_cen_mer < -TWO_PI || lon_cen_mer > TWO_PI ) { Isin_error( &ISIN_BADPARAM, "Isin_for_init" ); return NULL; } if ( lon_cen_mer < PI ) lon_cen_mer += TWO_PI; if ( lon_cen_mer >= PI ) lon_cen_mer -= TWO_PI; if ( nrow < 2 || nrow > NROW_MAX ) { Isin_error( &ISIN_BADPARAM, "Isin_for_init" ); return NULL; } if ( ( nrow % 2 ) != 0 ) { Isin_error( &ISIN_BADPARAM, "Isin_for_init" ); return NULL; } if ( ijustify < 0 || ijustify > 2 ) { Isin_error( &ISIN_BADPARAM, "Isin_for_init" ); return NULL; } /* Allocate 'isin' data structure */ this = ( Isin_t * ) malloc( sizeof( Isin_t ) ); if ( this == NULL ) { Isin_error( &ISIN_BADALLOC, "Isin_for_init" ); return NULL; } /* Place parameters in static storage for common use ------------------------------------------------- R = sphere; lon_center = lon_cen_mer; false_easting = false_east; false_northing = false_north; zone = nrow; justify = ijustify; */ /* Report parameters to the user -----------------------------*/ ptitle("INTEGERIZED SINUSOIDAL"); radius(sphere); cenlon(lon_cen_mer); offsetp(false_east,false_north); genrpt_long(nrow, "Number of Latitudinal Zones: "); genrpt(ijustify, "Right Justify Columns Flag: "); /* Initialize data structure */ this->key = 0; this->false_east = false_east; this->false_north = false_north; this->sphere = sphere; this->sphere_inv = 1.0 / sphere; this->ang_size_inv = ( ( double ) nrow ) / PI; this->nrow = nrow; this->nrow_half = nrow / 2; this->lon_cen_mer = lon_cen_mer; this->ref_lon = lon_cen_mer - PI; if ( this->ref_lon < -PI ) this->ref_lon += TWO_PI; this->ijustify = ijustify; /* Allocate space for information about each row */ this->row = (Isin_row_t *)malloc(this->nrow_half * sizeof(Isin_row_t)); if ( this->row == NULL ) { free( this ); Isin_error( &ISIN_BADALLOC, "Isin_for_init" ); return NULL; } /* Do calculations for each row; calculations are only done for half * the rows because of the symmetry between the rows above the * equator and the ones below */ row = this->row; for ( irow = 0; irow < this->nrow_half; irow++, row++ ) { /* Calculate latitude at center of row */ clat = HALF_PI * ( 1.0 - ( ( double ) irow + 0.5 ) / this->nrow_half ); /* Calculate number of columns per row */ if ( ijustify < 2 ) row->ncol = (long)((2.0 * cos(clat) * nrow) + 0.5); else { /* make the number of columns even */ row->ncol = (long)((cos(clat) * nrow) + 0.5); row->ncol *= 2; } #ifdef CHECK_EDGE /* Check to be sure the are no less then three columns per row and that * there are exactly three columns at the poles */ if ( ijustify < 2 ) { if ( row->ncol < 3 || ( irow == 0 && row->ncol != 3 ) ) printf( " irow = %d ncol = %d\n", irow, row->ncol ); } else { if ( row->ncol < 6 || ( irow == 0 && row->ncol != 6 ) ) printf( " irow = %d ncol = %d\n", irow, row->ncol ); } #endif /* Must have at least one column */ if ( row->ncol < 1 ) row->ncol = 1; #ifdef CHECK_EDGE /* Calculate the minimum delta column (normalized by the number of * columns in the row) */ if ( ijustify < 2 ) dcol = fabs( ( 2.0 * cos( clat ) * nrow ) + 0.5 - row->ncol ); else dcol = 2.0 * fabs((cos(clat) * nrow) + 0.5 - (row->ncol/2)); dcol = dcol / row->ncol; if ( dcol < dcol_min ) dcol_min = dcol; if ( ijustify < 2 ) { dcol = fabs((2.0 * cos(clat) * nrow) + 0.5 - (row->ncol + 1)); dcol = dcol / ( row->ncol + 1 ); } else { dcol = 2.0 * fabs((cos(clat) * nrow) + 0.5 - ((row->ncol/2) + 1)); dcol = dcol / ( row->ncol + 2 ); } if ( dcol < dcol_min ) dcol_min = dcol; #endif /* Save the inverse of the number of columns */ row->ncol_inv = 1.0 / ( ( double ) row->ncol ); /* Calculate the column number of the column whose left edge touches the central meridian */ if ( ijustify == 1 ) row->icol_cen = ( row->ncol + 1 ) / 2; else row->icol_cen = row->ncol / 2; } /* for (irow... */ /* Get the number of columns at the equator */ ncol_cen = this->row[this->nrow_half - 1].ncol; #ifdef CHECK_EDGE /* Print the minimum delta column and its base 2 log */ log2_dcol_min = log( dcol_min ) / log( 2.0 ); printf( " dcol_min = %g log2_dcol_min = %g\n", dcol_min, log2_dcol_min ); /* Check to be sure the number of columns at the equator is twice the * number of rows */ if ( ncol_cen != nrow * 2 ) printf( " ncol_cen = %d nrow = %d\n", ncol_cen, nrow ); #endif /* Calculate the distance at the equator between * the centers of two columns (and the inverse) */ this->col_dist = ( TWO_PI * sphere ) / ncol_cen; this->col_dist_inv = ncol_cen / ( TWO_PI * sphere ); /* Give the data structure a valid key */ this->key = ISIN_KEY; /* All done */ return this; }