long Convert_Geodetic_To_OSSIM_MGRS (double Latitude, double Longitude, long Precision, char* OSSIM_MGRS) /* * Latitude : Latitude in radians (input) * Longitude : Longitude in radians (input) * OSSIM_MGRS : OSSIM_MGRS coordinate string (output) * */ { /* Convert_Geodetic_To_OSSIM_MGRS */ long error_code = OSSIM_MGRS_NO_ERROR; long zone; char hemisphere; double easting; double northing; if ((Latitude < -PI_OVER_2) || (Latitude > PI_OVER_2)) { /* Latitude out of range */ error_code |= OSSIM_MGRS_LAT_ERROR; } if ((Longitude < -PI) || (Longitude > (2*PI))) { /* Longitude out of range */ error_code |= OSSIM_MGRS_LON_ERROR; } if ((Precision < 0) || (Precision > MAX_PRECISION)) error_code |= OSSIM_MGRS_PRECISION_ERROR; if (!error_code) { if ((Latitude < MIN_UTM_LAT) || (Latitude > MAX_UTM_LAT)) { Set_UPS_Parameters (OSSIM_MGRS_a, OSSIM_MGRS_f); error_code |= Convert_Geodetic_To_UPS (Latitude, Longitude, &hemisphere, &easting, &northing); error_code |= Convert_UPS_To_OSSIM_MGRS (hemisphere, easting, northing, Precision, OSSIM_MGRS); } else { Set_UTM_Parameters (OSSIM_MGRS_a, OSSIM_MGRS_f, 0); error_code |= Convert_Geodetic_To_UTM (Latitude, Longitude, &zone, &hemisphere, &easting, &northing); error_code |= Convert_UTM_To_OSSIM_MGRS (zone, hemisphere, easting, northing, Precision, OSSIM_MGRS); } } return (error_code); } /* Convert_Geodetic_To_OSSIM_MGRS */
long Convert_Geodetic_To_MGRS (double Latitude, double Longitude, long Precision, char* MGRS) /* * The function Convert_Geodetic_To_MGRS converts Geodetic (latitude and * longitude) coordinates to an MGRS coordinate string, according to the * current ellipsoid parameters. If any errors occur, the error code(s) * are returned by the function, otherwise MGRS_NO_ERROR is returned. * * Latitude : Latitude in radians (input) * Longitude : Longitude in radians (input) * Precision : Precision level of MGRS string (input) * MGRS : MGRS coordinate string (output) * */ { /* Convert_Geodetic_To_MGRS */ long zone; char hemisphere; double easting; double northing; long temp_error_code = MGRS_NO_ERROR; long error_code = MGRS_NO_ERROR; if ((Latitude < -PI_OVER_2) || (Latitude > PI_OVER_2)) { /* Latitude out of range */ error_code |= MGRS_LAT_ERROR; } if ((Longitude < -PI) || (Longitude > (2*PI))) { /* Longitude out of range */ error_code |= MGRS_LON_ERROR; } if ((Precision < 0) || (Precision > MAX_PRECISION)) error_code |= MGRS_PRECISION_ERROR; if (!error_code) { if ((Latitude < MIN_UTM_LAT) || (Latitude > MAX_UTM_LAT)) { temp_error_code = Set_UPS_Parameters (MGRS_a, MGRS_f); if(!temp_error_code) { temp_error_code = Convert_Geodetic_To_UPS (Latitude, Longitude, &hemisphere, &easting, &northing); if(!temp_error_code) { error_code |= Convert_UPS_To_MGRS (hemisphere, easting, northing, Precision, MGRS); } else { if(temp_error_code & UPS_LAT_ERROR) error_code |= MGRS_LAT_ERROR; if(temp_error_code & UPS_LON_ERROR) error_code |= MGRS_LON_ERROR; } } else { if(temp_error_code & UPS_A_ERROR) error_code |= MGRS_A_ERROR; if(temp_error_code & UPS_INV_F_ERROR) error_code |= MGRS_INV_F_ERROR; } } else { temp_error_code = Set_UTM_Parameters (MGRS_a, MGRS_f, 0); if(!temp_error_code) { temp_error_code = Convert_Geodetic_To_UTM (Latitude, Longitude, &zone, &hemisphere, &easting, &northing); if(!temp_error_code) error_code |= UTM_To_MGRS (zone, hemisphere, Longitude, Latitude, easting, northing, Precision, MGRS); else { if(temp_error_code & UTM_LAT_ERROR) error_code |= MGRS_LAT_ERROR; if(temp_error_code & UTM_LON_ERROR) error_code |= MGRS_LON_ERROR; if(temp_error_code & UTM_ZONE_OVERRIDE_ERROR) error_code |= MGRS_ZONE_ERROR; if(temp_error_code & UTM_EASTING_ERROR) error_code |= MGRS_EASTING_ERROR; if(temp_error_code & UTM_NORTHING_ERROR) error_code |= MGRS_NORTHING_ERROR; } } else { if(temp_error_code & UTM_A_ERROR) error_code |= MGRS_A_ERROR; if(temp_error_code & UTM_INV_F_ERROR) error_code |= MGRS_INV_F_ERROR; if(temp_error_code & UTM_ZONE_OVERRIDE_ERROR) error_code |= MGRS_ZONE_ERROR; } } } return (error_code); } /* Convert_Geodetic_To_MGRS */
long UTM_To_MGRS (long Zone, char Hemisphere, double Longitude, double Latitude, double Easting, double Northing, long Precision, char *MGRS) /* * The function UTM_To_MGRS calculates an MGRS coordinate string * based on the zone, latitude, easting and northing. * * Zone : Zone number (input) * Hemisphere: Hemisphere (input) * Longitude : Longitude in radians (input) * Latitude : Latitude in radians (input) * Easting : Easting (input) * Northing : Northing (input) * Precision : Precision (input) * MGRS : MGRS coordinate string (output) */ { /* BEGIN UTM_To_MGRS */ double pattern_offset; /* Northing offset for 3rd letter */ double grid_easting; /* Easting used to derive 2nd letter of MGRS */ double grid_northing; /* Northing used to derive 3rd letter of MGRS */ long ltr2_low_value; /* 2nd letter range - low number */ long ltr2_high_value; /* 2nd letter range - high number */ int letters[MGRS_LETTERS]; /* Number location of 3 letters in alphabet */ double divisor; double rounded_easting; long temp_error_code = MGRS_NO_ERROR; long error_code = MGRS_NO_ERROR; divisor = pow (10.0, (5 - Precision)); rounded_easting = Round_MGRS (Easting/divisor) * divisor; /* Special check for rounding to (truncated) eastern edge of zone 31V */ if ((Zone == 31) && (((Latitude >= 56.0 * DEG_TO_RAD) && (Latitude < 64.0 * DEG_TO_RAD)) && ((Longitude >= 3.0 * DEG_TO_RAD) || (rounded_easting >= 500000.0)))) { /* Reconvert to UTM zone 32 */ Set_UTM_Parameters (MGRS_a, MGRS_f, 32); temp_error_code = Convert_Geodetic_To_UTM (Latitude, Longitude, &Zone, &Hemisphere, &Easting, &Northing); if(temp_error_code) { if(temp_error_code & UTM_LAT_ERROR) error_code |= MGRS_LAT_ERROR; if(temp_error_code & UTM_LON_ERROR) error_code |= MGRS_LON_ERROR; if(temp_error_code & UTM_ZONE_OVERRIDE_ERROR) error_code |= MGRS_ZONE_ERROR; if(temp_error_code & UTM_EASTING_ERROR) error_code |= MGRS_EASTING_ERROR; if(temp_error_code & UTM_NORTHING_ERROR) error_code |= MGRS_NORTHING_ERROR; return error_code; } else /* Round easting value using new easting */ Easting = Round_MGRS (Easting/divisor) * divisor; } else Easting = rounded_easting; /* Round northing values */ Northing = Round_MGRS (Northing/divisor) * divisor; if( Latitude <= 0.0 && Northing == 1.0e7) { Latitude = 0.0; Northing = 0.0; } Get_Grid_Values(Zone, <r2_low_value, <r2_high_value, &pattern_offset); error_code = Get_Latitude_Letter(Latitude, &letters[0]); if (!error_code) { grid_northing = Northing; while (grid_northing >= TWOMIL) { grid_northing = grid_northing - TWOMIL; } grid_northing = grid_northing + pattern_offset; if(grid_northing >= TWOMIL) grid_northing = grid_northing - TWOMIL; letters[2] = (long)(grid_northing / ONEHT); if (letters[2] > LETTER_H) letters[2] = letters[2] + 1; if (letters[2] > LETTER_N) letters[2] = letters[2] + 1; grid_easting = Easting; if (((letters[0] == LETTER_V) && (Zone == 31)) && (grid_easting == 500000.0)) grid_easting = grid_easting - 1.0; /* SUBTRACT 1 METER */ letters[1] = ltr2_low_value + ((long)(grid_easting / ONEHT) -1); if ((ltr2_low_value == LETTER_J) && (letters[1] > LETTER_N)) letters[1] = letters[1] + 1; Make_MGRS_String (MGRS, Zone, letters, grid_easting, Northing, Precision); } return error_code; } /* END UTM_To_MGRS */
void GRID_UTM (long *Zone, long *Letters, char *Hemisphere, double *Easting, double *Northing, long In_Precision, long *Error) { /* BEGIN GRID_UTM */ double fnltr; /* False northing for 3rd letter */ long ltrhi; /* 2nd letter range - High number */ long ltrlow; /* 2nd letter range - Low number */ long number; /* Value of ltrnum[0] + 1 */ /* double slam;*/ double slcm; /* Central meridian */ double sleast; /* Longitude east limit - UTM */ double slwest; /* Longitude west limit -UTM */ double sphi; /* Latitude (needed by UTMLIM) */ double spnor; /* North latitude limits based on 1st letter */ double spsou; /* South latitude limits based on 1st letter */ double xltr; /* Easting for 100,000 meter grid square */ double ylow; /* Lowest northing of area to nearest 100,000 */ double yltr; /* Northing for 100,000 meter grid square */ double yslow; /* Northing scaled down to less than 2 million*/ double Latitude = 0.0; double Longitude = 0.0; double divisor = 1.0; if ((*Zone == 32) && (Letters[0] == LETTER_X)) { *Error = TRUE; return; } if ((*Zone == 34) && (Letters[0] == LETTER_X)) { *Error = TRUE; return; } if ((*Zone == 36) && (Letters[0] == LETTER_X)) { *Error = TRUE; return; } number = Letters[0] + 1; sphi = 0.0; UTMLIM(&number,sphi,*Zone,&spsou,&spnor,&sleast,&slwest); Set_UTM_Parameters(OSSIM_MGRS_a,OSSIM_MGRS_f,*Zone); slcm = (double)(*Zone * 6 - 183) * DEGRAD; Convert_Geodetic_To_UTM(spsou,slcm,Zone,Hemisphere,&xltr,&yltr); ylow = ((double)((long)((double)((long)(yltr / ONEHT)) * ONEHT))); yslow = ylow; while (yslow >= TWOMIL) { yslow = yslow - TWOMIL; } yslow = ((double)((long)(yslow))); UTMSET(*Zone, <rlow, <rhi, &fnltr); LTR2UTM(Letters, ltrlow, ltrhi, Error, &xltr, &yltr, fnltr, yslow, ylow); *Easting = xltr + *Easting; *Northing = yltr + *Northing; /* check that point is within Zone Letter bounds */ Convert_UTM_To_Geodetic(*Zone,*Hemisphere,*Easting,*Northing,&Latitude,&Longitude); divisor = pow (10.0, In_Precision); if (((spsou - DEGRAD/divisor) <= Latitude) && (Latitude <= (spnor + DEGRAD/divisor))) return; else *Error = TRUE; return; }/* END OF GRID_UTM */
void UTMOSSIM_MGRS (long izone, long* ltrnum, double sphi, double x, double y) { /* BEGIN UTMMGRS */ /* * izone : Zone number. * ltrnum : Values of letters in the MGRS coordinate. * sphi : Latitude in radians. * x : Easting. * y : Northing. * * UTMMGRS CALLS THE FOLLOWING ROUTINES: * * GPTUTM * UTMLIM * UTMSET */ double fnltr; /* False northing for 3rd letter */ double slcm; /* Central meridian - longitude of origin */ double sleast; /* Longitude east limit - UTM */ double slwest; /* Longitude west limit -UTM */ double spnor; /* MGRS north latitude limits based on 1st letter */ double spsou; /* MGRS south latitude limits based on 1st letter */ double xltr; /* Easting used to derive 2nd letter of MGRS */ double yltr; /* Northing used to derive 3rd letter of MGRS */ long ltrlow; /* 2nd letter range - low number */ long ltrhi; /* 2nd letter range - high number */ char hemisphere; UTMSET(izone, <rlow, <rhi, &fnltr); ltrnum[0] = LETTER_A; UTMLIM(<rnum[0], sphi, izone, &spsou, &spnor, &sleast, &slwest); slcm = (double)(izone * 6 - 183) * DEGRAD; /* GPTUTM(a, recf, spsou, slcm, &izone, &yltr, &xltr, (long)1); */ Set_UTM_Parameters(OSSIM_MGRS_a,OSSIM_MGRS_f,izone); Convert_Geodetic_To_UTM(spsou,slcm,&izone,&hemisphere,&xltr,&yltr); yltr = (double)((long)(y + RND5)); if (((double)((long)(yltr + RND5))) == ((double)((long)(1.e7 + RND5)))) { yltr = (double)((long)(yltr - 1.e0 + RND5)); } while (yltr >= TWOMIL) { yltr = yltr - TWOMIL; } yltr = yltr - fnltr; if (yltr < ZERO) { yltr = yltr + TWOMIL; } ltrnum[2] = (long)((yltr + RND1) / ONEHT); if (ltrnum[2] > LETTER_H) { ltrnum[2] = ltrnum[2] + 1; } if (ltrnum[2] > LETTER_N) { ltrnum[2] = ltrnum[2] + 1; } xltr = (double)((long)(x)); if (((ltrnum[0] == LETTER_V) && (izone == 31)) && (((double)((long)(xltr + RND5))) == ((double)((long)(5.e5 + RND5))))) { xltr = (double)((long)(xltr - 1.e0 + RND5)); /* SUBTRACT 1 METER */ } ltrnum[1] = ltrlow + ((long)((xltr + RND1) / ONEHT) -1); if ((ltrlow == LETTER_J) && (ltrnum[1] > LETTER_N)) { ltrnum[1] = ltrnum[1] + 1; } return; } /* END UTMMGRS */