~ubuntu-branches/ubuntu/raring/geotranz/raring

« back to all changes in this revision

Viewing changes to geotrans2/src/strtoval.c

  • Committer: Bazaar Package Importer
  • Author(s): Roberto Lumbreras
  • Date: 2008-10-17 14:43:09 UTC
  • Revision ID: james.westby@ubuntu.com-20081017144309-jb7uzfi1y1lvez8j
Tags: upstream-2.4.2
ImportĀ upstreamĀ versionĀ 2.4.2

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#include <string.h>
 
2
#include <stdlib.h>
 
3
#include <stdio.h>
 
4
#include <ctype.h>
 
5
#include <math.h>
 
6
#include "engine.h"
 
7
#include "strtoval.h"
 
8
#include "strndup.h"
 
9
 
 
10
#define Lat_String 1
 
11
#define Long_String 2
 
12
 
 
13
int leading_zeros = 0;
 
14
char Lat_Long_Sep = ' ';
 
15
Range Long_Range = _180_180;
 
16
long Lat_Long_Prec = Tenth_of_Second;
 
17
 
 
18
void Show_Leading_Zeros(int lz)
 
19
{
 
20
  leading_zeros = lz;
 
21
}
 
22
 
 
23
void Set_Separator(char sep)
 
24
{
 
25
  Lat_Long_Sep = sep;
 
26
}
 
27
 
 
28
void Set_Long_Range(Range range)
 
29
{
 
30
  Long_Range = range;
 
31
}
 
32
 
 
33
char Get_Separator()
 
34
{
 
35
  return (Lat_Long_Sep);
 
36
}
 
37
 
 
38
Range Get_Long_Range()
 
39
{
 
40
  return (Long_Range);
 
41
}
 
42
 
 
43
void Set_Lat_Long_Precision(long precis)
 
44
{
 
45
  Lat_Long_Prec = precis;
 
46
}
 
47
 
 
48
 
 
49
SVC_Status String_to_Projection(const char *str, Coordinate_Type *val)
 
50
{
 
51
  SVC_Status error_Code = SVC_Success;
 
52
  /* Note: any name that is a substring of another name must come before that name */
 
53
  if (strstr("GEODETIC", str))
 
54
  {
 
55
    *val = Geodetic;
 
56
  }
 
57
  else if (strstr("GEOREF", str))
 
58
  {
 
59
    *val = GEOREF;
 
60
  }
 
61
  else if (strstr("GEOCENTRIC", str))
 
62
  {
 
63
    *val = Geocentric;
 
64
  }
 
65
  else if (strstr("LOCAL CARTESIAN", str))
 
66
  {
 
67
    *val = Local_Cartesian;
 
68
  }
 
69
  else if (strstr("MILITARY GRID REFERENCE SYSTEM (MGRS)", str))
 
70
  {
 
71
    *val = MGRS;
 
72
  }
 
73
  else if (strstr("UNITED STATES NATIONAL GRID (USNG)", str))
 
74
  {
 
75
    *val = USNG;
 
76
  }
 
77
  else if (strstr("MERCATOR", str))
 
78
  {
 
79
    *val = Mercator;
 
80
  }
 
81
  else if (strstr("OBLIQUE MERCATOR", str))
 
82
  {
 
83
    *val = Oblique_Mercator;
 
84
  }
 
85
  else if (strstr("TRANSVERSE MERCATOR", str))
 
86
  {
 
87
    *val = Transverse_Mercator;
 
88
  }
 
89
  else if (strstr("UNIVERSAL TRANSVERSE MERCATOR (UTM)", str))
 
90
  {
 
91
    *val = UTM;
 
92
  }
 
93
  else if (strstr("STEREOGRAPHIC", str))
 
94
  {
 
95
    *val = Stereographic;
 
96
  }
 
97
  else if (strstr("POLAR STEREOGRAPHIC", str))
 
98
  {
 
99
    *val = Polar_Stereo;
 
100
  }
 
101
  else if (strstr("UNIVERSAL POLAR STEREOGRAPHIC (UPS)", str))
 
102
  {
 
103
    *val = UPS;
 
104
  }
 
105
  else if (strstr("ALBERS EQUAL AREA CONIC", str))
 
106
  {
 
107
    *val = Albers_Equal_Area_Conic;
 
108
  }
 
109
  else if (strstr("AZIMUTHAL EQUIDISTANT", str))
 
110
  {
 
111
    *val = Azimuthal_Equidistant;
 
112
  }
 
113
  else if (strstr("BONNE", str))
 
114
  {
 
115
    *val = Bonne;
 
116
  }
 
117
  else if (strstr("BRITISH NATIONAL GRID (BNG)", str))
 
118
  {
 
119
    *val = BNG;
 
120
  }
 
121
  else if (strstr("CASSINI", str))
 
122
  {
 
123
    *val = Cassini;
 
124
  }
 
125
  else if (strstr("ECKERT IV", str))
 
126
  {
 
127
    *val = Eckert4;
 
128
  }
 
129
  else if (strstr("ECKERT VI", str))
 
130
  {
 
131
    *val = Eckert6;
 
132
  }
 
133
  else if (strstr("EQUIDISTANT CYLINDRICAL", str))
 
134
  {
 
135
    *val = Equidistant_Cylindrical;
 
136
  }
 
137
  else if (strstr("GLOBAL AREA REFERENCE SYSTEM (GARS)", str))
 
138
  {
 
139
    *val = GARS;
 
140
  }
 
141
  else if (strstr("GNOMONIC", str))
 
142
  {
 
143
    *val = Gnomonic;
 
144
  }
 
145
  else if ((strstr("LAMBERT CONFORMAL CONIC", str)) ||
 
146
           (strstr("LAMBERT CONFORMAL CONIC (2 PARALLEL)", str)))
 
147
  {
 
148
    *val = Lambert_Conformal_Conic_2;
 
149
  }
 
150
  else if (strstr("LAMBERT CONFORMAL CONIC (1 PARALLEL)", str))
 
151
  {
 
152
    *val = Lambert_Conformal_Conic_1;
 
153
  }
 
154
  else if (strstr("MILLER CYLINDRICAL", str))
 
155
  {
 
156
    *val = Miller_Cylindrical;
 
157
  }
 
158
  else if (strstr("MOLLWEIDE", str))
 
159
  {
 
160
    *val = Mollweide;
 
161
  }
 
162
  else if ((strstr("NEY'S (MODIFIED LAMBERT CONFORMAL CONIC)", str)) ||
 
163
           (strstr("NEYS (MODIFIED LAMBERT CONFORMAL CONIC)", str)))
 
164
  {
 
165
    *val = Neys;
 
166
  }
 
167
  else if (strstr("NEW ZEALAND MAP GRID (NZMG)", str))
 
168
  {
 
169
    *val = NZMG;
 
170
  }
 
171
  else if (strstr("ORTHOGRAPHIC", str))
 
172
  {
 
173
    *val = Orthographic;
 
174
  }
 
175
  else if (strstr("POLYCONIC", str))
 
176
  {
 
177
    *val = Polyconic;
 
178
  }
 
179
  else if (strstr("SINUSOIDAL", str))
 
180
  {
 
181
    *val = Sinusoidal;
 
182
  }
 
183
  else if (strstr("CYLINDRICAL EQUAL AREA", str))
 
184
  {
 
185
    *val = Cylindrical_Equal_Area;
 
186
  }
 
187
  else if (strstr("TRANSVERSE CYLINDRICAL EQUAL AREA", str))
 
188
  {
 
189
    *val = Transverse_Cylindrical_Equal_Area;
 
190
  }
 
191
  else if (strstr("VAN DER GRINTEN", str))
 
192
  {
 
193
    *val = Van_der_Grinten;
 
194
  }
 
195
  else
 
196
  {
 
197
    error_Code = SVC_Invalid_Projection_String;
 
198
  }
 
199
 
 
200
  return error_Code;
 
201
}
 
202
 
 
203
 
 
204
SVC_Status Projection_to_String(const Coordinate_Type val, char str[32])
 
205
{
 
206
  SVC_Status error_Code = SVC_Success;
 
207
 
 
208
  switch (val)
 
209
  {
 
210
  case Geodetic:
 
211
    {
 
212
      strcpy(str, "Geodetic");
 
213
      break;
 
214
    }
 
215
  case GEOREF:
 
216
    {
 
217
      strcpy(str, "GEOREF");
 
218
      break;
 
219
    }
 
220
  case Geocentric:
 
221
    {
 
222
      strcpy(str, "Geocentric");
 
223
      break;
 
224
    }
 
225
  case Local_Cartesian:
 
226
    {
 
227
      strcpy(str, "Local Cartesian");
 
228
      break;
 
229
    }
 
230
  case MGRS:
 
231
    {
 
232
      strcpy(str, "Military Grid Reference System (MGRS)");
 
233
      break;
 
234
    }
 
235
  case USNG:
 
236
    {
 
237
      strcpy(str, "United States National Grid (USNG)");
 
238
      break;
 
239
    }
 
240
  case UTM:
 
241
    {
 
242
      strcpy(str, "Universal Transverse Mercator (UTM)");
 
243
      break;
 
244
    }
 
245
  case UPS:
 
246
    {
 
247
      strcpy(str, "Universal Polar Stereographic (UPS)");
 
248
      break;
 
249
    }
 
250
  case Albers_Equal_Area_Conic:
 
251
    {
 
252
      strcpy(str, "Albers Equal Area Conic");
 
253
      break;
 
254
    }
 
255
  case Azimuthal_Equidistant:
 
256
    {
 
257
      strcpy(str, "Azimuthal Equidistant");
 
258
      break;
 
259
    }
 
260
  case BNG:
 
261
    {
 
262
      strcpy(str, "British National Grid (BNG)");
 
263
      break;
 
264
    }
 
265
  case Bonne:
 
266
    {
 
267
      strcpy(str, "Bonne");
 
268
      break;
 
269
    }
 
270
  case Cassini:
 
271
    {
 
272
      strcpy(str, "Cassini");
 
273
      break;
 
274
    }
 
275
  case Cylindrical_Equal_Area:
 
276
    {
 
277
      strcpy(str, "Cylindrical Equal Area");
 
278
      break;
 
279
    }
 
280
  case Eckert4:
 
281
    {
 
282
      strcpy(str, "Eckert IV");
 
283
      break;
 
284
    }
 
285
  case Eckert6:
 
286
    {
 
287
      strcpy(str, "Eckert VI");
 
288
      break;
 
289
    }
 
290
  case Equidistant_Cylindrical:
 
291
    {
 
292
      strcpy(str, "Equidistant Cylindrical");
 
293
      break;
 
294
    }
 
295
  case GARS:
 
296
    {
 
297
      strcpy(str, "Global Area Reference System (GARS)");
 
298
      break;
 
299
    }
 
300
  case Gnomonic:
 
301
    {
 
302
      strcpy(str, "Gnomonic");
 
303
      break;
 
304
    }
 
305
  case Lambert_Conformal_Conic_1:
 
306
    {
 
307
      strcpy(str, "Lambert Conformal Conic (1 parallel)");
 
308
      break;
 
309
    }
 
310
  case Lambert_Conformal_Conic_2:
 
311
    {
 
312
      strcpy(str, "Lambert Conformal Conic (2 parallel)");
 
313
      break;
 
314
    }
 
315
  case Mercator:
 
316
    {
 
317
      strcpy(str, "Mercator");
 
318
      break;
 
319
    }
 
320
  case Miller_Cylindrical:
 
321
    {
 
322
      strcpy(str, "Miller Cylindrical");
 
323
      break;
 
324
    }
 
325
  case Mollweide:
 
326
    {
 
327
      strcpy(str, "Mollweide");
 
328
      break;
 
329
    }
 
330
  case Neys:
 
331
    {
 
332
      strcpy(str, "Ney's (Modified Lambert Conformal Conic)");
 
333
      break;
 
334
    }
 
335
  case NZMG:
 
336
    {
 
337
      strcpy(str, "New Zealand Map Grid (NZMG)");
 
338
      break;
 
339
    }
 
340
  case Oblique_Mercator:
 
341
    {
 
342
      strcpy(str, "Oblique Mercator");
 
343
      break;
 
344
    }
 
345
  case Orthographic:
 
346
    {
 
347
      strcpy(str, "Orthographic");
 
348
      break;
 
349
    }
 
350
  case Polar_Stereo:
 
351
    {
 
352
      strcpy(str, "Polar Stereographic");
 
353
      break;
 
354
    }
 
355
  case Polyconic:
 
356
    {
 
357
      strcpy(str, "Polyconic");
 
358
      break;
 
359
    }
 
360
  case Sinusoidal:
 
361
    {
 
362
      strcpy(str, "Sinusoidal");
 
363
      break;
 
364
    }
 
365
  case Stereographic:
 
366
    {
 
367
      strcpy(str, "Stereographic");
 
368
      break;
 
369
    }
 
370
  case Transverse_Mercator:
 
371
    {
 
372
      strcpy(str, "Transverse Mercator");
 
373
      break;
 
374
    }
 
375
  case Transverse_Cylindrical_Equal_Area:
 
376
    {
 
377
      strcpy(str, "Transverse Cylindrical Equal Area");
 
378
      break;
 
379
    }
 
380
  case Van_der_Grinten:
 
381
    {
 
382
      strcpy(str, "Van der Grinten");
 
383
      break;
 
384
    }
 
385
  default:
 
386
    error_Code = SVC_Invalid_Projection_Value;
 
387
    break;
 
388
  }
 
389
 
 
390
  return error_Code;
 
391
}
 
392
 
 
393
 
 
394
double Round_Meter(const double Value)
 
395
/*
 
396
 *  The function Round Meter rounds the specified value, in meters, according to
 
397
 *  the current precision level.
 
398
 *  Value         : Value to be rounded                                 (input)
 
399
 */
 
400
{ /* Round_Meter */
 
401
  double avalue;
 
402
  double divisor = 1.0;
 
403
  double fraction;
 
404
  double ivalue;
 
405
  double result;
 
406
  long ival = 0;
 
407
  long sign = 1;
 
408
  switch (Lat_Long_Prec)
 
409
  {
 
410
  case Degree:
 
411
    {
 
412
      divisor = 100000.0;
 
413
      break;
 
414
    }
 
415
  case Ten_Minutes:
 
416
    {
 
417
      divisor = 10000.0;
 
418
      break;
 
419
    }
 
420
  case Minute:
 
421
    {
 
422
      divisor = 1000.0;
 
423
      break;
 
424
    }
 
425
  case Ten_Seconds:
 
426
    {
 
427
      divisor = 100.0;
 
428
      break;
 
429
    }
 
430
  case Second:
 
431
    {
 
432
      divisor = 10.0;
 
433
      break;
 
434
    }
 
435
  case Tenth_of_Second:
 
436
    {
 
437
      divisor = 1.0;
 
438
      break;
 
439
    }
 
440
  case Hundredth_of_Second:
 
441
    {
 
442
      divisor = 0.1;
 
443
      break;
 
444
    }
 
445
  case Thousandth_of_Second:
 
446
    {
 
447
      divisor = 0.01;
 
448
      break;
 
449
    }
 
450
  case Ten_Thousandth_of_Second:
 
451
    {
 
452
      divisor = 0.001;
 
453
      break;
 
454
    }
 
455
  }
 
456
  if (Value < 0.0)
 
457
    sign = -1;
 
458
  avalue = fabs (Value / divisor);
 
459
  fraction = modf (avalue, &ivalue);
 
460
  ival = (long)(ivalue);
 
461
  if ((fraction > 0.5) || ((fraction == 0.5) && (ival%2 == 1)))
 
462
    ivalue++;
 
463
  result = (double)(ivalue * divisor * sign);
 
464
  return ( result );
 
465
} /* Round_Meter */
 
466
 
 
467
 
 
468
SVC_Status Meter_to_String(const double meters, char str[15])
 
469
{
 
470
  SVC_Status error_Code = SVC_Success;
 
471
 
 
472
  double meter_Value = Round_Meter(meters);
 
473
 
 
474
  if (Lat_Long_Prec > 4)
 
475
    if (sprintf(str, "%1.*lf",(int)(Lat_Long_Prec - 5), meter_Value) <= 0)
 
476
      error_Code = SVC_Meter_to_String;
 
477
    else
 
478
      error_Code = SVC_Success;
 
479
  else
 
480
    if (sprintf(str, "%1.0lf", meter_Value) <= 0)
 
481
      error_Code = SVC_Meter_to_String;
 
482
    else
 
483
      error_Code = SVC_Success;
 
484
 
 
485
  return error_Code;
 
486
}
 
487
 
 
488
 
 
489
SVC_Status Long_Meter_to_String(const double meters, char str[15])
 
490
{
 
491
  SVC_Status error_Code = SVC_Success;
 
492
 
 
493
  double meter_Value = Round_Meter(meters);
 
494
 
 
495
  if (Lat_Long_Prec > 4)
 
496
    if (sprintf(str, "%1.*lf",(int)(Lat_Long_Prec - 5), meter_Value) <= 0)
 
497
      error_Code = SVC_Meter_to_String;
 
498
    else
 
499
      error_Code = SVC_Success;
 
500
  else
 
501
    if (sprintf(str, "%1.0lf", meter_Value) <= 0)
 
502
      error_Code = SVC_Meter_to_String;
 
503
    else
 
504
      error_Code = SVC_Success;
 
505
 
 
506
  return error_Code;
 
507
}
 
508
 
 
509
 
 
510
SVC_Status String_to_Double(const char *str, double *val)
 
511
{
 
512
  char *placeholder = NULL;
 
513
  SVC_Status error_Code = SVC_Success;
 
514
 
 
515
  *val = 0;
 
516
  if (Valid_Number(str))
 
517
  {
 
518
    *val = strtod(str,&placeholder);
 
519
    return (error_Code);
 
520
  }
 
521
  else
 
522
    return (SVC_Error);
 
523
}
 
524
 
 
525
 
 
526
long Valid_Number(const char *str)
 
527
{
 
528
  int i = 0;
 
529
  long valid = 1;
 
530
  int length;
 
531
  int deci = 0;
 
532
 
 
533
  if (str)
 
534
  {
 
535
    length = strlen(str);
 
536
    if ((i<length) && ((str[i] == '-') || (str[i] == '+')))
 
537
      i ++;
 
538
    while (valid && (i < length))
 
539
    {
 
540
      if (!isdigit(str[i]))
 
541
      {
 
542
        if ((str[i] == '.') && !deci)
 
543
        {
 
544
          i++;
 
545
          deci = 1;
 
546
        }
 
547
        else
 
548
          valid = 0;
 
549
      }
 
550
      else
 
551
        i++;
 
552
    }
 
553
  }
 
554
  return (valid);
 
555
}
 
556
 
 
557
 
 
558
SVC_Status String_to_Long(const char *str, long *val)
 
559
{
 
560
  long return_Parameter = 0;
 
561
  char *placeholder = NULL;
 
562
  SVC_Status error_Code = SVC_Success;
 
563
 
 
564
  if (str && strlen(str))
 
565
  {
 
566
    return_Parameter = strtol(str, &placeholder, 10);
 
567
  }
 
568
 
 
569
  if ((return_Parameter == 0) && (placeholder == str))
 
570
  {
 
571
    error_Code = SVC_String_to_Long;
 
572
  }
 
573
 
 
574
  *val = return_Parameter;
 
575
  return error_Code;
 
576
}
 
577
 
 
578
 
 
579
long Valid_Coord(char *str, long Type)
 
580
{
 
581
  long Decimal = false;
 
582
  long Signed = false;
 
583
  long Separators = 0;
 
584
  long Valid = true;
 
585
  long Length;
 
586
  long Pos = 0;
 
587
 
 
588
  if (str != NULL)
 
589
  {
 
590
    Length = strlen(str);
 
591
    if ((Pos<Length) && ((str[Pos] == '-') || (str[Pos] == '+')))
 
592
    {
 
593
      Signed = true;
 
594
      Pos ++;
 
595
    }
 
596
    while ((Pos < Length) && Valid)
 
597
    {
 
598
      if (str[Pos] == '.')
 
599
      {
 
600
        if (Decimal)
 
601
          Valid = false;
 
602
        else
 
603
        {
 
604
          Decimal = true;
 
605
          Pos++;
 
606
        }
 
607
      }
 
608
      else if (isdigit(str[Pos]))
 
609
      {
 
610
        Pos++;
 
611
      }
 
612
      else if ((str[Pos] == ' ') || (str[Pos] == '/') || (str[Pos] == ':'))
 
613
      {
 
614
        if (Separators >= 3)
 
615
          Valid = false;
 
616
        else
 
617
        {
 
618
          Pos++;
 
619
          Separators++;
 
620
        }
 
621
      }
 
622
      else if (isalpha(str[Pos]))
 
623
      {
 
624
        str[Pos] = (char)toupper(str[Pos]);
 
625
        if ((((str[Pos] == 'N') || (str[Pos] == 'S')) && (Type == Lat_String))
 
626
            || (((str[Pos] == 'W') || (str[Pos] == 'E')) && (Type == Long_String)))
 
627
        {
 
628
          if (Signed)
 
629
            Valid = false;
 
630
          Pos++;
 
631
          if (Pos != Length)
 
632
            Valid = false;
 
633
        }
 
634
        else
 
635
          Valid = false;
 
636
      }
 
637
      else
 
638
        Valid = false;
 
639
    }
 
640
  }
 
641
  return (Valid);
 
642
}
 
643
 
 
644
 
 
645
SVC_Status String_to_Longitude(const char *str, double *val)
 
646
{
 
647
  SVC_Status error_Code = SVC_Success;
 
648
 
 
649
  double degrees = 0.0;
 
650
  double minutes = 0.0;
 
651
  double seconds = 0.0;
 
652
  long sign = 1;
 
653
  char *reference_Pointer;
 
654
  char *parse_String;
 
655
  char *next_Str = 0;
 
656
  /* Longitudes may have the following format :
 
657
 
 
658
     PDDD/MM/SS.FFH
 
659
     PDDD/MM.FFFFH
 
660
     PDDD.FFFFFFH
 
661
 
 
662
     where these are defined as follows
 
663
     P = optional plus/minus
 
664
     D = degrees (up to three places)
 
665
     M = minutes (up to two places)
 
666
     S = seconds (up to two places)
 
667
     F = floating-point precision (up to 6 places)
 
668
     H = optional hemisphere (NSEW)
 
669
     / = separator character, one of ':' , '/' , ' '
 
670
  */
 
671
  if (strlen(str))
 
672
  {
 
673
    reference_Pointer = strdup_(str);
 
674
    parse_String = reference_Pointer;
 
675
    if (Valid_Coord(reference_Pointer,Long_String))
 
676
    {
 
677
      if (parse_String[0] == '-')
 
678
      {
 
679
        sign = -1;
 
680
      }
 
681
 
 
682
      next_Str = strtok(parse_String, ":/ ");
 
683
 
 
684
      if (next_Str != NULL)
 
685
      {
 
686
        degrees = atof(next_Str);
 
687
      }
 
688
 
 
689
      next_Str = strtok(NULL, ":/ ");
 
690
 
 
691
      if (next_Str != NULL)
 
692
      {
 
693
        minutes = atof(next_Str);
 
694
      }
 
695
 
 
696
      next_Str = strtok(NULL, ":/ ");
 
697
 
 
698
      if (next_Str != NULL)
 
699
      {
 
700
        seconds = atof(next_Str);
 
701
      }
 
702
 
 
703
      if ((strchr(str, 'N') != NULL) ||
 
704
          (strchr(str, 'S') != NULL))
 
705
      {
 
706
        error_Code = SVC_Inappropriate_Hemisphere;
 
707
      }
 
708
 
 
709
      if (((next_Str = strchr(str, 'E')) != NULL)
 
710
          || ((next_Str = strchr(str, 'e')) != NULL))
 
711
      {
 
712
        if (sign == -1)
 
713
        {
 
714
          error_Code = SVC_Sign_and_Hemisphere;
 
715
        }
 
716
 
 
717
        if (next_Str[1] != '\0')
 
718
        {
 
719
          error_Code = SVC_Misplaced_Hemisphere;
 
720
        }
 
721
      }
 
722
 
 
723
      if (((next_Str = strchr(str, 'W')) != NULL)
 
724
          || ((next_Str = strchr(str, 'w')) != NULL))
 
725
      {
 
726
        if (sign == -1)
 
727
        {
 
728
          error_Code = SVC_Sign_and_Hemisphere;
 
729
        }
 
730
 
 
731
        if (next_Str[1] == '\0')
 
732
        {
 
733
          sign = -1;
 
734
        }
 
735
        else
 
736
        {
 
737
          error_Code = SVC_Misplaced_Hemisphere;
 
738
        }
 
739
      }
 
740
 
 
741
      if (seconds >= 60 || seconds < 0)
 
742
      {
 
743
        error_Code = SVC_Seconds_out_of_Bounds;
 
744
      }
 
745
 
 
746
      if (minutes >= 60 || minutes < 0)
 
747
      {
 
748
        error_Code = SVC_Minutes_out_of_Bounds;
 
749
      }
 
750
 
 
751
      if ((degrees == -180 || degrees == 360) &&
 
752
          ((minutes != 0) || (seconds != 0)))
 
753
      {
 
754
        error_Code = SVC_Minutes_or_Seconds_Overflow;
 
755
      }
 
756
 
 
757
      /* Convert DMS to fractional degrees */
 
758
      *val = ( fabs(degrees) + (minutes / 60.0) + (seconds / 3600.0) ) * sign;
 
759
 
 
760
      /* Convert longitude to be between -180 and 180 */
 
761
                        if (*val > 180)
 
762
                                *val -= 360;
 
763
 
 
764
      if ((*val > 360) || (*val < -180))
 
765
      {
 
766
        error_Code = SVC_Degrees_out_of_Bounds;
 
767
      }
 
768
 
 
769
      if (error_Code != SVC_Success)
 
770
      {
 
771
        *val = 0;
 
772
      }
 
773
 
 
774
      free(reference_Pointer);
 
775
    }
 
776
    else
 
777
      error_Code = SVC_Error;
 
778
  }
 
779
  return error_Code;
 
780
}/* String_to_Longitude */
 
781
 
 
782
 
 
783
SVC_Status Longitude_to_String(const double in_longitude, char str[15],
 
784
                               boole use_NSEW, boole use_Minutes, boole use_Seconds)
 
785
{/* Longitude_to_String */
 
786
  double degrees = 0.0;
 
787
  double longitude;
 
788
  char degrees_As_String[15];
 
789
  long starting_Index = 0;
 
790
  long ending_Index = 13;
 
791
  SVC_Status error_Code = SVC_Success;
 
792
 
 
793
  longitude = in_longitude;
 
794
  if ((longitude > -0.00000001) && (longitude < 0.00000001))
 
795
  {
 
796
    longitude = 0.0;
 
797
  }
 
798
  strcpy(degrees_As_String,"              ");
 
799
  switch (Long_Range)
 
800
  {
 
801
  case _180_180:
 
802
    {
 
803
      if (longitude > 180)
 
804
        degrees = fabs(longitude - 360);
 
805
      else
 
806
        degrees = fabs(longitude);
 
807
      break;
 
808
    }
 
809
  case _0_360:
 
810
    {
 
811
      if (longitude < 0)
 
812
        degrees = longitude + 360;
 
813
      else
 
814
        degrees = longitude;
 
815
      break;
 
816
    }
 
817
  }
 
818
  Degrees_to_String(degrees, &degrees_As_String[1], use_Minutes, use_Seconds, Long_String);
 
819
  ending_Index = strlen(&degrees_As_String[1]) + 1;
 
820
  starting_Index = 1;
 
821
  switch (Long_Range)
 
822
  {
 
823
  case _180_180:
 
824
    {
 
825
      if (use_NSEW)
 
826
      {
 
827
        if ((longitude > 180) || (longitude < 0))
 
828
          degrees_As_String[ending_Index] = 'W';
 
829
        else
 
830
          degrees_As_String[ending_Index] = 'E';
 
831
      }
 
832
      else
 
833
      {
 
834
        if ((longitude > 180) || (longitude < 0))
 
835
        {
 
836
          degrees_As_String[0] = '-';
 
837
          starting_Index = 0;
 
838
        }
 
839
      }
 
840
      break;
 
841
    }
 
842
  case _0_360:
 
843
    {
 
844
      if (use_NSEW)
 
845
        degrees_As_String[ending_Index] = 'E';
 
846
      break;
 
847
    }
 
848
  }
 
849
  degrees_As_String[ending_Index+1] = '\0';
 
850
  strcpy(str, &degrees_As_String[starting_Index]);
 
851
  return error_Code;
 
852
}
 
853
 
 
854
 
 
855
void Round_DMS(double *val, long place)
 
856
{
 
857
  double temp;
 
858
  double fraction;
 
859
  double int_temp;
 
860
 
 
861
  temp = *val * pow(10,place);
 
862
 
 
863
  fraction = modf(temp, &int_temp);
 
864
  if (((temp - int_temp) > 0.5) ||
 
865
      (((temp - int_temp) == 0.5) && (fmod(int_temp,2.0) == 1.0)))
 
866
    *val = (int_temp + 1.0) / pow(10,place);
 
867
  else
 
868
    *val = int_temp / pow(10,place);
 
869
}
 
870
 
 
871
 
 
872
void Degrees_to_String(double degrees, char *str, boole use_Minutes, boole use_Seconds, long Type)
 
873
{
 
874
  double minutes = 0.0;
 
875
  double seconds = 0.0;
 
876
  long integer_Degrees = 0;
 
877
  long integer_Minutes = 0;
 
878
  long integer_Seconds = 0;
 
879
  int j;
 
880
 
 
881
  if ((!use_Minutes) || (Lat_Long_Prec == 0))
 
882
  { /* Decimal Degrees */
 
883
    Round_DMS(&degrees, Lat_Long_Prec);
 
884
    if(leading_zeros)
 
885
    {
 
886
      if(Type == Lat_String)
 
887
        if(fabs(degrees) < 10)
 
888
          sprintf(str,"0%1.*lf",(int)Lat_Long_Prec,degrees);
 
889
        else
 
890
          sprintf(str,"%1.*lf",(int)Lat_Long_Prec,degrees);
 
891
      else
 
892
        if(fabs(degrees) < 10)
 
893
          sprintf(str,"00%1.*lf",(int)Lat_Long_Prec,degrees);
 
894
        else if(fabs(degrees) < 100)
 
895
          sprintf(str,"0%1.*lf",(int)Lat_Long_Prec,degrees);
 
896
        else
 
897
          sprintf(str,"%1.*lf",(int)Lat_Long_Prec,degrees);
 
898
    }
 
899
    else
 
900
      sprintf(str,"%1.*lf",(int)Lat_Long_Prec,degrees);
 
901
  }
 
902
  else if ((use_Minutes && !use_Seconds) || (Lat_Long_Prec <= 2))
 
903
  { /* Degrees & Minutes */
 
904
    integer_Degrees = (long)degrees;
 
905
    minutes = (degrees - integer_Degrees) * 60.0;
 
906
    Round_DMS(&minutes, Lat_Long_Prec - 2);
 
907
    integer_Minutes = (long)minutes;
 
908
    if (integer_Minutes >= 60)
 
909
    {
 
910
      integer_Minutes -= 60;
 
911
      integer_Degrees += 1;
 
912
    }
 
913
    if (Lat_Long_Prec <= 2)
 
914
    {
 
915
      if(leading_zeros)
 
916
      {
 
917
        if(Type == Lat_String)
 
918
          if(fabs(degrees) < 10)
 
919
            j = sprintf(str,"0%ld%c",integer_Degrees,Lat_Long_Sep);
 
920
          else
 
921
            j = sprintf(str,"%ld%c",integer_Degrees,Lat_Long_Sep);
 
922
        else
 
923
          if(fabs(degrees) < 10)
 
924
            j = sprintf(str,"00%ld%c",integer_Degrees,Lat_Long_Sep);
 
925
          else if(fabs(degrees) < 100)
 
926
            j = sprintf(str,"0%ld%c",integer_Degrees,Lat_Long_Sep);
 
927
          else
 
928
            j = sprintf(str,"%ld%c",integer_Degrees,Lat_Long_Sep);
 
929
 
 
930
        if(integer_Minutes < 10)
 
931
          j += sprintf(str + j,"0%ld",integer_Minutes);
 
932
        else
 
933
          j += sprintf(str + j,"%ld",integer_Minutes);
 
934
      }
 
935
      else
 
936
        sprintf(str,"%ld%c%ld",integer_Degrees,Lat_Long_Sep,integer_Minutes);
 
937
    }
 
938
    else
 
939
    {
 
940
      if (minutes >= 60)
 
941
        minutes -= 60;
 
942
      if(leading_zeros)
 
943
      {
 
944
        if(Type == Lat_String)
 
945
          if(fabs(degrees) < 10)
 
946
            j = sprintf(str,"0%ld%c",integer_Degrees,Lat_Long_Sep);
 
947
          else
 
948
            j = sprintf(str,"%ld%c",integer_Degrees,Lat_Long_Sep);
 
949
        else
 
950
          if(fabs(degrees) < 10)
 
951
            j = sprintf(str,"00%ld%c",integer_Degrees,Lat_Long_Sep);
 
952
          else if(fabs(degrees) < 100)
 
953
            j = sprintf(str,"0%ld%c",integer_Degrees,Lat_Long_Sep);
 
954
          else
 
955
            j = sprintf(str,"%ld%c",integer_Degrees,Lat_Long_Sep);
 
956
 
 
957
        if(integer_Minutes < 10)
 
958
          j += sprintf(str + j,"0%1.*lf",(int)Lat_Long_Prec-2,minutes);
 
959
        else
 
960
          j += sprintf(str + j,"%1.*lf",(int)Lat_Long_Prec-2,minutes);
 
961
      }
 
962
      else
 
963
        sprintf(str,"%ld%c%1.*lf",integer_Degrees,Lat_Long_Sep,(int)Lat_Long_Prec-2,minutes);
 
964
    }
 
965
  }
 
966
  else
 
967
  { /* Degrees, Minutes, & Seconds */
 
968
    integer_Degrees = (long)degrees;
 
969
    minutes = (degrees - integer_Degrees) * 60.0;
 
970
    integer_Minutes = (long)minutes;
 
971
    seconds = (minutes - integer_Minutes) * 60.0;
 
972
    Round_DMS(&seconds, Lat_Long_Prec - 4);
 
973
    integer_Seconds = (long)seconds;
 
974
    if (integer_Seconds >= 60)
 
975
    {
 
976
      integer_Seconds -= 60;
 
977
      integer_Minutes += 1;
 
978
      if (integer_Minutes >= 60)
 
979
      {
 
980
        integer_Degrees += 1;
 
981
        integer_Minutes -= 60;
 
982
      }
 
983
    }
 
984
 
 
985
    if (Lat_Long_Prec <= 4)
 
986
    {
 
987
      if(leading_zeros)
 
988
      {
 
989
        if(Type == Lat_String)
 
990
          if(fabs(degrees) < 10)
 
991
            j = sprintf(str,"0%ld%c",integer_Degrees,Lat_Long_Sep);
 
992
          else
 
993
            j = sprintf(str,"%ld%c",integer_Degrees,Lat_Long_Sep);
 
994
        else
 
995
          if(fabs(degrees) < 10)
 
996
            j = sprintf(str,"00%ld%c",integer_Degrees,Lat_Long_Sep);
 
997
          else if(fabs(degrees) < 100)
 
998
            j = sprintf(str,"0%ld%c",integer_Degrees,Lat_Long_Sep);
 
999
          else
 
1000
            j = sprintf(str,"%ld%c",integer_Degrees,Lat_Long_Sep);
 
1001
 
 
1002
        if(integer_Minutes < 10)
 
1003
          j += sprintf(str + j,"0%ld%c",integer_Minutes,Lat_Long_Sep);
 
1004
        else
 
1005
          j += sprintf(str + j,"%ld%c",integer_Minutes,Lat_Long_Sep);
 
1006
 
 
1007
        if(integer_Seconds < 10)
 
1008
          j += sprintf(str + j,"0%ld",integer_Seconds);
 
1009
        else
 
1010
          j += sprintf(str + j,"%ld",integer_Seconds);
 
1011
      }
 
1012
      else
 
1013
        sprintf(str,"%ld%c%ld%c%ld",integer_Degrees,Lat_Long_Sep,integer_Minutes,Lat_Long_Sep,integer_Seconds);
 
1014
    }
 
1015
    else
 
1016
    {
 
1017
      if (seconds >= 60)
 
1018
      {
 
1019
        seconds -= 60;
 
1020
      }
 
1021
      if(leading_zeros)
 
1022
      {
 
1023
        if(Type == Lat_String)
 
1024
          if(fabs(degrees) < 10)
 
1025
            j = sprintf(str,"0%ld%c",integer_Degrees,Lat_Long_Sep);
 
1026
          else
 
1027
            j = sprintf(str,"%ld%c",integer_Degrees,Lat_Long_Sep);
 
1028
        else
 
1029
          if(fabs(degrees) < 10)
 
1030
            j = sprintf(str,"00%ld%c",integer_Degrees,Lat_Long_Sep);
 
1031
          else if(fabs(degrees) < 100)
 
1032
            j = sprintf(str,"0%ld%c",integer_Degrees,Lat_Long_Sep);
 
1033
          else
 
1034
            j = sprintf(str,"%ld%c",integer_Degrees,Lat_Long_Sep);
 
1035
 
 
1036
        if(integer_Minutes < 10)
 
1037
          j += sprintf(str + j,"0%ld%c",integer_Minutes,Lat_Long_Sep);
 
1038
        else
 
1039
          j += sprintf(str + j,"%ld%c",integer_Minutes,Lat_Long_Sep);
 
1040
 
 
1041
        if(integer_Seconds < 10)
 
1042
          j += sprintf(str + j,"0%1.*lf",(int)Lat_Long_Prec-4,seconds);
 
1043
        else
 
1044
          j += sprintf(str + j,"%1.*lf",(int)Lat_Long_Prec-4,seconds);
 
1045
      }
 
1046
      else
 
1047
        sprintf(str,"%ld%c%ld%c%1.*lf",integer_Degrees,Lat_Long_Sep,integer_Minutes,Lat_Long_Sep,(int)Lat_Long_Prec-4,seconds);
 
1048
    }
 
1049
  }
 
1050
}
 
1051
 
 
1052
 
 
1053
SVC_Status String_to_Latitude(const char *str, double *val)
 
1054
{
 
1055
  SVC_Status error_Code = SVC_Success;
 
1056
 
 
1057
  double degrees = 0.0;
 
1058
  double minutes = 0.0;
 
1059
  double seconds = 0.0;
 
1060
  long sign = 1;
 
1061
  char *reference_Pointer;
 
1062
  char *parse_String;
 
1063
  char *next_Str = 0;
 
1064
  /* Longitudes may have the following format :
 
1065
 
 
1066
     PDD/MM/SS.FFH
 
1067
     PDD/MM.FFFFH
 
1068
     PDD.FFFFFFH
 
1069
 
 
1070
     where these are defined as follows
 
1071
     P = optional plus/minus
 
1072
     D = degrees (up to two places)
 
1073
     M = minutes (up to two places)
 
1074
     S = seconds (up to two places)
 
1075
     F = floating-point precision (up to 6 places)
 
1076
     H = optional hemisphere (NSEW)
 
1077
     / = separator character, one of / : sp
 
1078
  */
 
1079
 
 
1080
  if (strlen(str))
 
1081
  {
 
1082
    reference_Pointer = strdup_(str);
 
1083
    parse_String = reference_Pointer;
 
1084
    if (Valid_Coord(reference_Pointer,Lat_String))
 
1085
    {
 
1086
      if (parse_String[0] == '-')
 
1087
      {
 
1088
        sign = -1;
 
1089
      }
 
1090
 
 
1091
      next_Str = strtok(parse_String, ":/ ");
 
1092
 
 
1093
      if (next_Str != NULL)
 
1094
      {
 
1095
        degrees = atof(next_Str);
 
1096
      }
 
1097
 
 
1098
      next_Str = strtok(NULL, ":/ ");
 
1099
 
 
1100
      if (next_Str != NULL)
 
1101
      {
 
1102
        minutes = atof(next_Str);
 
1103
      }
 
1104
 
 
1105
      next_Str = strtok(NULL, ":/ ");
 
1106
 
 
1107
      if (next_Str != NULL)
 
1108
      {
 
1109
        seconds = atof(next_Str);
 
1110
      }
 
1111
 
 
1112
      if ((strchr(str, 'W') != NULL) ||
 
1113
          (strchr(str, 'E') != NULL))
 
1114
      {
 
1115
        error_Code = SVC_Inappropriate_Hemisphere;
 
1116
      }
 
1117
 
 
1118
      if (((next_Str = strchr(str, 'N')) != NULL)
 
1119
          || ((next_Str = strchr(str, 'n')) != NULL))
 
1120
      {
 
1121
        if (sign == -1)
 
1122
        {
 
1123
          error_Code = SVC_Sign_and_Hemisphere;
 
1124
        }
 
1125
 
 
1126
        if (next_Str[1] != '\0')
 
1127
        {
 
1128
          error_Code = SVC_Misplaced_Hemisphere;
 
1129
        }
 
1130
      }
 
1131
 
 
1132
      if (((next_Str = strchr(str, 'S')) != NULL)
 
1133
          || ((next_Str = strchr(str, 's')) != NULL))
 
1134
      {
 
1135
        if (sign == -1)
 
1136
        {
 
1137
          error_Code = SVC_Sign_and_Hemisphere;
 
1138
        }
 
1139
 
 
1140
        if (next_Str[1] == '\0')
 
1141
        {
 
1142
          sign = -1;
 
1143
        }
 
1144
        else
 
1145
        {
 
1146
          error_Code = SVC_Misplaced_Hemisphere;
 
1147
        }
 
1148
      }
 
1149
 
 
1150
      if (seconds >= 60 || seconds < 0)
 
1151
      {
 
1152
        error_Code = SVC_Seconds_out_of_Bounds;
 
1153
      }
 
1154
 
 
1155
      if (minutes >= 60 || minutes < 0)
 
1156
      {
 
1157
        error_Code = SVC_Minutes_out_of_Bounds;
 
1158
      }
 
1159
 
 
1160
      if (degrees < -90 || degrees > 90)
 
1161
      {
 
1162
        error_Code = SVC_Degrees_out_of_Bounds;
 
1163
      }
 
1164
 
 
1165
      if ((degrees == -90 || degrees == 90) &&
 
1166
          ((minutes != 0) || (seconds != 0)))
 
1167
      {
 
1168
        error_Code = SVC_Minutes_or_Seconds_Overflow;
 
1169
      }
 
1170
 
 
1171
      /* Convert DMS to fractional degrees */
 
1172
      *val = (double)( fabs(degrees) + (minutes / 60) + (seconds / 3600) ) * sign;
 
1173
 
 
1174
      if (error_Code != SVC_Success)
 
1175
      {
 
1176
        *val = 0;
 
1177
      }
 
1178
 
 
1179
      free(reference_Pointer);
 
1180
    }
 
1181
    else
 
1182
      error_Code = SVC_Error;
 
1183
  }
 
1184
  return error_Code;
 
1185
}
 
1186
 
 
1187
 
 
1188
SVC_Status Latitude_to_String(const double in_latitude, char str[14],
 
1189
                              boole use_NSEW, boole use_Minutes, boole use_Seconds)
 
1190
{
 
1191
  double degrees = fabs(in_latitude);
 
1192
  double latitude;
 
1193
  char degrees_As_String[14];
 
1194
  long starting_Index = 1;
 
1195
  SVC_Status error_Code = SVC_Success;
 
1196
  long ending_Index = 12;
 
1197
 
 
1198
  latitude = in_latitude;
 
1199
  if ((latitude > -0.00000001) && (latitude < 0.00000001))
 
1200
  {
 
1201
    latitude = 0.0;
 
1202
  }
 
1203
  strcpy(degrees_As_String,"             ");
 
1204
  Degrees_to_String(degrees, &degrees_As_String[1], use_Minutes, use_Seconds, Lat_String);
 
1205
  ending_Index = strlen(&degrees_As_String[1]) + 1;
 
1206
 
 
1207
  if (use_NSEW)
 
1208
  {
 
1209
    if (latitude < 0)
 
1210
    {
 
1211
      degrees_As_String[ending_Index] = 'S';
 
1212
    }
 
1213
    else
 
1214
    {
 
1215
      degrees_As_String[ending_Index] = 'N';
 
1216
    }
 
1217
  }
 
1218
  else
 
1219
  {
 
1220
    if (latitude < 0)
 
1221
    {
 
1222
      degrees_As_String[0] = '-';
 
1223
      starting_Index = 0;
 
1224
    }
 
1225
  }
 
1226
  degrees_As_String[ending_Index+1] = '\0';
 
1227
  strcpy(str, &degrees_As_String[starting_Index]);
 
1228
  return error_Code;
 
1229
}
 
1230
 
 
1231
 
 
1232
SVC_Status Zone_to_String(const long zone, char str[3])
 
1233
{
 
1234
  SVC_Status error_Code = SVC_Success;
 
1235
 
 
1236
  if( zone < 10 )
 
1237
  {
 
1238
    if (sprintf(str, "%1d", zone) <= 0)
 
1239
    {
 
1240
      error_Code = SVC_Zone_to_String;
 
1241
    }
 
1242
  }
 
1243
  else
 
1244
  {
 
1245
    if (sprintf(str, "%2d", zone) <= 0)
 
1246
    {
 
1247
      error_Code = SVC_Zone_to_String;
 
1248
    }
 
1249
  }
 
1250
 
 
1251
  return error_Code;
 
1252
}
 
1253
 
 
1254
 
 
1255
SVC_Status Ellipsoidal_Height_to_String(const double ellipsoidal_Height, char str[15])
 
1256
{
 
1257
  return Long_Meter_to_String(ellipsoidal_Height, str);
 
1258
}
 
1259
 
 
1260
 
 
1261
SVC_Status Scale_Factor_to_String(const double scale_Factor, char str[8])
 
1262
{
 
1263
  SVC_Status error_Code = SVC_Success;
 
1264
 
 
1265
  if (sprintf(str, "%.5f", scale_Factor) <= 0)
 
1266
  {
 
1267
    error_Code = SVC_Scale_Factor_to_String;
 
1268
  }
 
1269
 
 
1270
  return error_Code;
 
1271
}
 
1272
 
 
1273
 
 
1274
void Error_Prefix
 
1275
( const Input_or_Output Direction,
 
1276
  const Coordinate_Type System,
 
1277
  char  *Separator,
 
1278
  char  *String)
 
1279
{
 
1280
  char   *in_out;
 
1281
  if (Direction == Input)
 
1282
    in_out = "Input";
 
1283
  else
 
1284
    in_out = "Output";
 
1285
  switch (System)
 
1286
  {
 
1287
  case Geocentric:
 
1288
    {
 
1289
      sprintf(String,"%s%s%s%s",in_out," Geocentric Coordinates:",Separator,Separator);
 
1290
      break;
 
1291
    }
 
1292
  case Geodetic:
 
1293
    {
 
1294
      sprintf(String,"%s%s%s%s",in_out," Geodetic Coordinates:",Separator,Separator);
 
1295
      break;
 
1296
    }
 
1297
  case GEOREF:
 
1298
    {
 
1299
      sprintf(String,"%s%s%s%s",in_out," GEOREF Coordinates:",Separator,Separator);
 
1300
      break;
 
1301
    }
 
1302
  case Albers_Equal_Area_Conic:
 
1303
    {
 
1304
      sprintf(String,"%s%s%s%s",in_out," Albers Equal Area Conic Projection:",Separator,Separator);
 
1305
      break;
 
1306
    }
 
1307
  case Azimuthal_Equidistant:
 
1308
    {
 
1309
      sprintf(String,"%s%s%s%s",in_out," Azimuthal Equidistant Projection:",Separator,Separator);
 
1310
      break;
 
1311
    }
 
1312
  case BNG:
 
1313
    {
 
1314
      sprintf(String,"%s%s%s%s",in_out," British National Grid Coordinates:",Separator,Separator);
 
1315
      break;
 
1316
    }
 
1317
  case Bonne:
 
1318
    {
 
1319
      sprintf(String,"%s%s%s%s",in_out," Bonne Projection:",Separator,Separator);
 
1320
      break;
 
1321
    }
 
1322
  case Cassini:
 
1323
    {
 
1324
      sprintf(String,"%s%s%s%s",in_out," Cassini Projection:",Separator,Separator);
 
1325
      break;
 
1326
    }
 
1327
  case Cylindrical_Equal_Area:
 
1328
    {
 
1329
      sprintf(String,"%s%s%s%s",in_out," Cylindrical Equal Area Projection:",Separator,Separator);
 
1330
      break;
 
1331
    }
 
1332
  case Eckert4:
 
1333
    {
 
1334
      sprintf(String,"%s%s%s%s",in_out," Eckert IV Projection:",Separator,Separator);
 
1335
      break;
 
1336
    }
 
1337
  case Eckert6:
 
1338
    {
 
1339
      sprintf(String,"%s%s%s%s",in_out," Eckert VI Projection:",Separator,Separator);
 
1340
      break;
 
1341
    }
 
1342
  case Equidistant_Cylindrical:
 
1343
    {
 
1344
      sprintf(String,"%s%s%s%s",in_out," Equidistant Cylindrical Projection:",Separator,Separator);
 
1345
      break;
 
1346
    }
 
1347
  case GARS:
 
1348
    {
 
1349
      sprintf(String,"%s%s%s%s",in_out," GARS Coordinates:",Separator,Separator);
 
1350
      break;
 
1351
    }
 
1352
  case Gnomonic:
 
1353
    {
 
1354
      sprintf(String,"%s%s%s%s",in_out," Gnomonic Projection:",Separator,Separator);
 
1355
      break;
 
1356
    }
 
1357
  case Lambert_Conformal_Conic_1:
 
1358
    {
 
1359
      sprintf(String,"%s%s%s%s",in_out," Lambert Conformal Conic (1 parallel) Projection:",Separator,Separator);
 
1360
      break;
 
1361
    }
 
1362
  case Lambert_Conformal_Conic_2:
 
1363
    {
 
1364
      sprintf(String,"%s%s%s%s",in_out," Lambert Conformal Conic (2 parallel) Projection:",Separator,Separator);
 
1365
      break;
 
1366
    }
 
1367
  case Local_Cartesian:
 
1368
    {
 
1369
      sprintf(String,"%s%s%s%s",in_out," Local Cartesian Coordinates:",Separator,Separator);
 
1370
      break;
 
1371
    }
 
1372
  case Mercator:
 
1373
    {
 
1374
      sprintf(String,"%s%s%s%s",in_out," Mercator Projection:",Separator,Separator);
 
1375
      break;
 
1376
    }
 
1377
  case MGRS:
 
1378
    {
 
1379
      sprintf(String,"%s%s%s%s",in_out," MGRS Coordinates:",Separator,Separator);
 
1380
      break;
 
1381
    }
 
1382
  case Miller_Cylindrical:
 
1383
    {
 
1384
      sprintf(String,"%s%s%s%s",in_out," Miller Cylindrical Projection:",Separator,Separator);
 
1385
      break;
 
1386
    }
 
1387
  case Mollweide:
 
1388
    {
 
1389
      sprintf(String,"%s%s%s%s",in_out," Mollweide Projection:",Separator,Separator);
 
1390
      break;
 
1391
    }
 
1392
  case Neys:
 
1393
    {
 
1394
      sprintf(String,"%s%s%s%s",in_out," Ney's Projection:",Separator,Separator);
 
1395
      break;
 
1396
    }
 
1397
  case NZMG:
 
1398
    {
 
1399
      sprintf(String,"%s%s%s%s",in_out," New Zealand Map Grid Projection:",Separator,Separator);
 
1400
      break;
 
1401
    }
 
1402
  case Oblique_Mercator:
 
1403
    {
 
1404
      sprintf(String,"%s%s%s%s",in_out," Oblique Mercator Projection:",Separator,Separator);
 
1405
      break;
 
1406
    }
 
1407
  case Orthographic:
 
1408
    {
 
1409
      sprintf(String,"%s%s%s%s",in_out," Orthographic Projection:",Separator,Separator);
 
1410
      break;
 
1411
    }
 
1412
  case Polar_Stereo:
 
1413
    {
 
1414
      sprintf(String,"%s%s%s%s",in_out," Polar Stereographic Projection:",Separator,Separator);
 
1415
      break;
 
1416
    }
 
1417
  case Polyconic:
 
1418
    {
 
1419
      sprintf(String,"%s%s%s%s",in_out," Polyconic Projection:",Separator,Separator);
 
1420
      break;
 
1421
    }
 
1422
  case Sinusoidal:
 
1423
    {
 
1424
      sprintf(String,"%s%s%s%s",in_out," Sinusoidal Projection:",Separator,Separator);
 
1425
      break;
 
1426
    }
 
1427
  case Stereographic:
 
1428
    {
 
1429
      sprintf(String,"%s%s%s%s",in_out," Stereographic Projection:",Separator,Separator);
 
1430
      break;
 
1431
    }
 
1432
  case Transverse_Cylindrical_Equal_Area:
 
1433
    {
 
1434
      sprintf(String,"%s%s%s%s",in_out," Transverse Cylindrical Equal Area Projection:",Separator,Separator);
 
1435
      break;
 
1436
    }
 
1437
  case Transverse_Mercator:
 
1438
    {
 
1439
      sprintf(String,"%s%s%s%s",in_out," Transverse Mercator Projection:",Separator,Separator);
 
1440
      break;
 
1441
    }
 
1442
  case UPS:
 
1443
    {
 
1444
      sprintf(String,"%s%s%s%s",in_out," UPS Coordinates:",Separator,Separator);
 
1445
      break;
 
1446
    }
 
1447
  case USNG:
 
1448
    {
 
1449
      sprintf(String,"%s%s%s%s",in_out," USNG Coordinates:",Separator,Separator);
 
1450
      break;
 
1451
    }
 
1452
  case UTM:
 
1453
    {
 
1454
      sprintf(String,"%s%s%s%s",in_out," UTM Coordinates:",Separator,Separator);
 
1455
      break;
 
1456
    }
 
1457
  case Van_der_Grinten:
 
1458
    {
 
1459
      sprintf(String,"%s%s%s%s",in_out," Van der Grinten Projection:",Separator,Separator);
 
1460
      break;
 
1461
    }
 
1462
  } /* switch */
 
1463
}
 
1464
 
 
1465
void Error_Append (char *New_String,
 
1466
                   char *Separator,
 
1467
                   char *String)
 
1468
{
 
1469
  strcat(String,New_String);
 
1470
  strcat(String,Separator);
 
1471
}