103 #define DEG_TO_RAD 0.017453292519943295
104 #define RAD_TO_DEG 57.29577951308232087
131 #define MGRS_LETTERS 3
132 #define ONEHT 100000.e0
133 #define TWOMIL 2000000.e0
136 #define PI 3.14159265358979323e0
137 #define PI_OVER_2 (PI / 2.0e0)
139 #define MIN_EASTING 100000
140 #define MAX_EASTING 900000
141 #define MIN_NORTHING 0
142 #define MAX_NORTHING 10000000
143 #define MAX_PRECISION 5
144 #define MIN_UTM_LAT ( (-80 * PI) / 180.0 )
145 #define MAX_UTM_LAT ( (84 * PI) / 180.0 )
147 #define MIN_EAST_NORTH 0
148 #define MAX_EAST_NORTH 4000000
179 {{
LETTER_C, 1100000.0, -72.0, -80.5, 0.0},
180 {
LETTER_D, 2000000.0, -64.0, -72.0, 2000000.0},
181 {
LETTER_E, 2800000.0, -56.0, -64.0, 2000000.0},
182 {
LETTER_F, 3700000.0, -48.0, -56.0, 2000000.0},
183 {
LETTER_G, 4600000.0, -40.0, -48.0, 4000000.0},
184 {
LETTER_H, 5500000.0, -32.0, -40.0, 4000000.0},
185 {
LETTER_J, 6400000.0, -24.0, -32.0, 6000000.0},
186 {
LETTER_K, 7300000.0, -16.0, -24.0, 6000000.0},
187 {
LETTER_L, 8200000.0, -8.0, -16.0, 8000000.0},
188 {
LETTER_M, 9100000.0, 0.0, -8.0, 8000000.0},
190 {
LETTER_P, 800000.0, 16.0, 8.0, 0.0},
191 {
LETTER_Q, 1700000.0, 24.0, 16.0, 0.0},
192 {
LETTER_R, 2600000.0, 32.0, 24.0, 2000000.0},
193 {
LETTER_S, 3500000.0, 40.0, 32.0, 2000000.0},
194 {
LETTER_T, 4400000.0, 48.0, 40.0, 4000000.0},
195 {
LETTER_U, 5300000.0, 56.0, 48.0, 4000000.0},
196 {
LETTER_V, 6200000.0, 64.0, 56.0, 6000000.0},
197 {
LETTER_W, 7000000.0, 72.0, 64.0, 6000000.0},
198 {
LETTER_X, 7900000.0, 84.5, 72.0, 6000000.0}};
236 *min_northing = Latitude_Band_Table[letter-2].
min_northing;
241 *min_northing = Latitude_Band_Table[letter-3].
min_northing;
246 *min_northing = Latitude_Band_Table[letter-4].
min_northing;
305 if (lat_deg >= 72 && lat_deg < 84.5)
307 else if (lat_deg > -80.5 && lat_deg < 72)
310 *letter = Latitude_Band_Table[(int)temp].letter;
336 while (MGRS[i] ==
' ')
339 while (isdigit((
unsigned char)MGRS[i]))
346 *zone_exists =
FALSE;
365 double fraction = modf (value, &ivalue);
366 ival = (int)(ivalue);
367 if ((fraction > 0.5) || ((fraction == 0.5) && (ival%2 == 1)))
396 char alphabet[] =
"ABCDEFGHIJKLMNOPQRSTUVWXYZ";
401 i =
sprintf (MGRS+i,
"%2.2d",Zone);
403 strncpy(MGRS,
" ", 2);
406 MGRS[i++] = alphabet[Letters[j]];
410 divisor = pow (10.0, (5 - Precision));
411 Easting = fmod (Easting, 100000.0);
412 if (Easting >= 99999.5)
414 east = (int)(Easting/divisor);
415 Northing = fmod (Northing, 100000.0);
416 if (Northing >= 99999.5)
418 north = (int)(Northing/divisor);
422 sprintf(MGRS+i,
"%05d %05d", east, north);
425 sprintf(MGRS+i,
"%04d %04d", east, north);
428 sprintf(MGRS+i,
"%03d %03d", east, north);
431 sprintf(MGRS+i,
"%02d %02d", east, north);
434 sprintf(MGRS+i,
"%01d %01d", east, north);
466 while (MGRS[i] ==
' ')
469 while (isdigit((
unsigned char)MGRS[i]))
477 strncpy (zone_string, MGRS+j, 2);
479 sscanf (zone_string,
"%d", Zone);
480 if ((*Zone < 1) || (*Zone > 60))
489 while (isalpha((
unsigned char)MGRS[i]))
492 if (num_letters == 3)
495 Letters[0] = (toupper((
unsigned char)MGRS[j]) - (int)
'A');
498 Letters[1] = (toupper((
unsigned char)MGRS[j+1]) - (int)
'A');
501 Letters[2] = (toupper((
unsigned char)MGRS[j+2]) - (int)
'A');
508 while (isdigit((
unsigned char)MGRS[
i]))
511 if ((num_digits <= 10) && (num_digits%2 == 0))
515 char north_string[6];
524 strncpy (east_string, MGRS+j, n);
526 sscanf (east_string,
"%d", &east);
527 strncpy (north_string, MGRS+j+n, n);
529 sscanf (north_string,
"%d", &north);
530 multiplier = pow (10.0, 5 - n);
531 *Easting = east * multiplier;
532 *Northing = north * multiplier;
549 int* ltr2_high_value,
550 double *pattern_offset)
567 set_number = zone % 6;
578 if ((set_number == 1) || (set_number == 4))
583 else if ((set_number == 2) || (set_number == 5))
588 else if ((set_number == 3) || (set_number == 6))
597 if ((set_number % 2) == 0)
598 *pattern_offset = 500000.0;
600 *pattern_offset = 0.0;
604 if ((set_number % 2) == 0)
605 *pattern_offset = 1500000.0;
607 *pattern_offset = 1000000.00;
634 double pattern_offset;
636 double grid_northing;
641 double rounded_easting;
645 divisor = pow (10.0, (5 - Precision));
646 rounded_easting =
Round_MGRS (Easting/divisor) * divisor;
649 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))))
670 Easting =
Round_MGRS (Easting/divisor) * divisor;
673 Easting = rounded_easting;
676 Northing =
Round_MGRS (Northing/divisor) * divisor;
678 if( Latitude <= 0.0 && Northing == 1.0e7)
684 Get_Grid_Values(Zone, <r2_low_value, <r2_high_value, &pattern_offset);
690 grid_northing = Northing;
692 while (grid_northing >=
TWOMIL)
694 grid_northing = grid_northing -
TWOMIL;
696 grid_northing = grid_northing + pattern_offset;
697 if(grid_northing >=
TWOMIL)
698 grid_northing = grid_northing -
TWOMIL;
700 letters[2] = (int)(grid_northing /
ONEHT);
702 letters[2] = letters[2] + 1;
705 letters[2] = letters[2] + 1;
707 grid_easting = Easting;
708 if (((letters[0] ==
LETTER_V) && (Zone == 31)) && (grid_easting == 500000.0))
709 grid_easting = grid_easting - 1.0;
711 letters[1] = ltr2_low_value + ((int)(grid_easting /
ONEHT) -1);
713 letters[1] = letters[1] + 1;
723 char *Ellipsoid_Code)
735 double inv_f = 1 /
f;
742 if ((inv_f < 250) || (inv_f > 350))
758 char* Ellipsoid_Code)
803 if ((Longitude < -
PI) || (Longitude > (2*
PI)))
844 error_code |=
UTM_To_MGRS (zone, hemisphere, Longitude, Latitude, easting, northing, Precision, MGRS);
988 if ((Zone < 1) || (Zone > 60))
990 if ((Hemisphere !=
'S') && (Hemisphere !=
'N'))
1012 error_code =
UTM_To_MGRS (Zone, Hemisphere, Longitude, latitude, Easting, Northing, Precision, MGRS);
1014 return (error_code);
1037 double min_northing;
1038 double northing_offset;
1040 int ltr2_high_value;
1041 double pattern_offset;
1042 double upper_lat_limit;
1043 double lower_lat_limit;
1044 double grid_easting;
1045 double grid_northing;
1049 double Longitude = 0.0;
1050 double divisor = 1.0;
1054 error_code =
Break_MGRS_String (MGRS, Zone, letters, Easting, Northing, &in_precision);
1061 if ((letters[0] ==
LETTER_X) && ((*Zone == 32) || (*Zone == 34) || (*Zone == 36)))
1070 Get_Grid_Values(*Zone, <r2_low_value, <r2_high_value, &pattern_offset);
1075 if ((letters[1] < ltr2_low_value) || (letters[1] > ltr2_high_value) || (letters[2] >
LETTER_V))
1080 double row_letter_northing = (double)(letters[2]) *
ONEHT;
1081 grid_easting = (double)((letters[1]) - ltr2_low_value + 1) *
ONEHT;
1083 grid_easting = grid_easting -
ONEHT;
1086 row_letter_northing = row_letter_northing -
ONEHT;
1089 row_letter_northing = row_letter_northing -
ONEHT;
1091 if (row_letter_northing >=
TWOMIL)
1092 row_letter_northing = row_letter_northing -
TWOMIL;
1097 grid_northing = row_letter_northing - pattern_offset;
1098 if(grid_northing < 0)
1101 grid_northing += northing_offset;
1103 if(grid_northing < min_northing)
1106 *Easting = grid_easting + *Easting;
1107 *Northing = grid_northing + *Northing;
1111 if (!utm_error_code)
1114 if (!utm_error_code)
1116 divisor = pow (10.0, in_precision);
1120 if (!(((lower_lat_limit -
DEG_TO_RAD/divisor) <= latitude) && (latitude <= (upper_lat_limit +
DEG_TO_RAD/divisor))))
1148 return (error_code);
1171 double false_easting;
1172 double false_northing;
1173 double grid_easting;
1174 double grid_northing;
1181 if ((Hemisphere !=
'N') && (Hemisphere !=
'S'))
1191 divisor = pow (10.0, (5 - Precision));
1192 Easting =
Round_MGRS (Easting/divisor) * divisor;
1193 Northing =
Round_MGRS (Northing/divisor) * divisor;
1195 if (Hemisphere ==
'N')
1202 index = letters[0] - 22;
1215 false_easting = UPS_Constant_Table[letters[0]].
false_easting;
1219 grid_northing = Northing;
1220 grid_northing = grid_northing - false_northing;
1221 letters[2] = (int)(grid_northing /
ONEHT);
1224 letters[2] = letters[2] + 1;
1227 letters[2] = letters[2] + 1;
1229 grid_easting = Easting;
1230 grid_easting = grid_easting - false_easting;
1231 letters[1] = ltr2_low_value + ((int)(grid_easting /
ONEHT));
1236 letters[1] = letters[1] + 3;
1239 letters[1] = letters[1] + 2;
1244 letters[1] = letters[1] + 2;
1247 letters[1] = letters[1] + 1;
1250 letters[1] = letters[1] + 3;
1255 return (error_code);
1275 int ltr2_high_value;
1276 int ltr3_high_value;
1278 double false_easting;
1279 double false_northing;
1280 double grid_easting;
1281 double grid_northing;
1288 error_code =
Break_MGRS_String (MGRS, &zone, letters, Easting, Northing, &in_precision);
1299 index = letters[0] - 22;
1313 false_easting = UPS_Constant_Table[letters[0]].
false_easting;
1320 if ((letters[1] < ltr2_low_value) || (letters[1] > ltr2_high_value) ||
1324 (letters[2] > ltr3_high_value))
1329 grid_northing = (double)letters[2] *
ONEHT + false_northing;
1331 grid_northing = grid_northing -
ONEHT;
1334 grid_northing = grid_northing -
ONEHT;
1336 grid_easting = (double)((letters[1]) - ltr2_low_value) * ONEHT + false_easting;
1340 grid_easting = grid_easting - 300000.0;
1343 grid_easting = grid_easting - 200000.0;
1348 grid_easting = grid_easting - 200000.0;
1351 grid_easting = grid_easting -
ONEHT;
1354 grid_easting = grid_easting - 300000.0;
1357 *Easting = grid_easting + *Easting;
1358 *Northing = grid_northing + *Northing;
1362 return (error_code);
int Convert_UTM_To_MGRS(int Zone, char Hemisphere, double Easting, double Northing, int Precision, char *MGRS)
#define UTM_EASTING_ERROR
int Convert_MGRS_To_UTM(char *MGRS, int *Zone, char *Hemisphere, double *Easting, double *Northing)
#define MGRS_EASTING_ERROR
int sprintf(char *out, const char *format,...)
int Get_Latitude_Letter(double latitude, int *letter)
int Convert_Geodetic_To_MGRS(double Latitude, double Longitude, int Precision, char *MGRS)
int Convert_UTM_To_Geodetic(int Zone, char Hemisphere, double Easting, double Northing, double *Latitude, double *intitude)
int Check_Zone(char *MGRS, int *zone_exists)
struct Latitude_Band_Value Latitude_Band
#define MGRS_STRING_ERROR
int Set_UTM_Parameters(double a, double f, int override)
char MGRS_Ellipsoid_Code[3]
#define UTM_ZONE_OVERRIDE_ERROR
void Get_MGRS_Parameters(double *a, double *f, char *Ellipsoid_Code)
int Convert_UPS_To_MGRS(char Hemisphere, double Easting, double Northing, int Precision, char *MGRS)
#define UTM_NORTHING_ERROR
int Convert_Geodetic_To_UPS(double Latitude, double longitude, char *Hemisphere, double *Easting, double *Northing)
static const Latitude_Band Latitude_Band_Table[20]
const char * BESSEL_1841_NAMIBIA
#define MGRS_NORTHING_ERROR
int Get_Latitude_Range(int letter, double *north, double *south)
int Set_MGRS_Parameters(double a, double f, char *Ellipsoid_Code)
int Set_UPS_Parameters(double a, double f)
static const UPS_Constant UPS_Constant_Table[4]
#define MGRS_PRECISION_ERROR
int Convert_Geodetic_To_UTM(double Latitude, double intitude, int *Zone, char *Hemisphere, double *Easting, double *Northing)
#define UPS_EASTING_ERROR
int Convert_MGRS_To_UPS(char *MGRS, char *Hemisphere, double *Easting, double *Northing)
int Convert_UPS_To_Geodetic(char Hemisphere, double Easting, double Northing, double *Latitude, double *longitude)
#define UPS_HEMISPHERE_ERROR
#define MGRS_HEMISPHERE_ERROR
int Make_MGRS_String(char *MGRS, int Zone, int Letters[MGRS_LETTERS], double Easting, double Northing, int Precision)
int Get_Latitude_Band_Min_Northing(int letter, double *min_northing, double *northing_offset)
void Get_Grid_Values(int zone, int *ltr2_low_value, int *ltr2_high_value, double *pattern_offset)
int Break_MGRS_String(char *MGRS, int *Zone, int Letters[MGRS_LETTERS], double *Easting, double *Northing, int *Precision)
int UTM_To_MGRS(int Zone, char Hemisphere, double Longitude, double Latitude, double Easting, double Northing, int Precision, char *MGRS)
#define UTM_HEMISPHERE_ERROR
int Convert_MGRS_To_Geodetic(char *MGRS, double *Latitude, double *Longitude)
int Round_MGRS(double value)
struct UPS_Constant_Value UPS_Constant