00001 #include <grass/gis.h>
00002 #include <grass/glocale.h>
00003 #include <unistd.h>
00004 #include <ctype.h>
00005 #include <string.h>
00006 #include <stdlib.h>
00007 #include <math.h>
00008
00009 static struct table
00010 {
00011 char *name;
00012 char *descr;
00013 double a;
00014 double e2;
00015 double f;
00016 } *table = NULL;
00017
00018 static int count = -1;
00019
00020
00021 static int get_a_e2_f (const char*, const char *, double *, double *, double*);
00022 void ellipsoid_table_file(char *);
00023 static int compare_table_names(const struct table *, const struct table *);
00024 static int read_ellipsoid_table(int );
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00062 int
00063 G_get_ellipsoid_parameters (double *a, double *e2)
00064 {
00065 int in_stat;
00066 char err[1024], ipath[1024], *str, *str1;
00067 struct Key_Value *proj_keys;
00068 static char *PERMANENT = "PERMANENT";
00069
00070
00071 G__file_name (ipath, "", PROJECTION_FILE, PERMANENT);
00072 if (access(ipath,0) !=0)
00073 {
00074 *a = 6378137.0 ;
00075 *e2 = .006694385 ;
00076 return 0;
00077 }
00078 proj_keys = G_read_key_value_file(ipath, &in_stat);
00079 if (in_stat !=0)
00080 {
00081 sprintf (err, _("Unable to open file %s in %s"),PROJECTION_FILE,PERMANENT);
00082 G_fatal_error (err);
00083 }
00084 if ((str = G_find_key_value("ellps",proj_keys))!=NULL) {
00085 if (strncmp(str,"sphere",6)==0) {
00086 str = G_find_key_value("a",proj_keys);
00087 if (str!=NULL) {
00088 if(sscanf(str,"%lf",a)!=1) {
00089 sprintf (err, _("invalid a: field %s in file %s in %s")
00090 ,str,PROJECTION_FILE,PERMANENT);
00091 G_fatal_error (err);
00092 }
00093 }
00094 else {
00095 *a = 6370997.0 ;
00096 }
00097 *e2 = 0.0 ;
00098 return 0;
00099 }
00100 else {
00101 if (G_get_ellipsoid_by_name (str, a, e2)==0) {
00102 sprintf (err, _("invalid ellipsoid %s in file %s in %s")
00103 ,str,PROJECTION_FILE,PERMANENT);
00104 G_fatal_error (err);
00105 }
00106 else return 1;
00107 }
00108 }
00109 else {
00110 str = G_find_key_value("a",proj_keys);
00111 str1 = G_find_key_value("es",proj_keys);
00112 if ((str!=NULL) && (str1!=NULL)) {
00113 if(sscanf(str,"%lf",a)!=1) {
00114 sprintf (err, _("invalid a: field %s in file %s in %s")
00115 ,str,PROJECTION_FILE,PERMANENT);
00116 G_fatal_error (err);
00117 }
00118 if(sscanf(str1,"%lf",e2)!=1) {
00119 sprintf (err, _("invalid es: field %s in file %s in %s")
00120 ,str,PROJECTION_FILE,PERMANENT);
00121 G_fatal_error (err);
00122 }
00123 return 1;
00124 }
00125 else {
00126 str = G_find_key_value("proj",proj_keys);
00127 if ((str==NULL)||(strcmp(str,"ll")==0)) {
00128 *a = 6378137.0 ;
00129 *e2 = .006694385 ;
00130 return 0;
00131 }
00132 else {
00133 sprintf (err, _("No ellipsoid info given in file %s in %s"),
00134 PROJECTION_FILE,PERMANENT);
00135 G_fatal_error (err);
00136 }
00137 }
00138 }
00139 return 1;
00140
00141 return 0;
00142 }
00143
00144
00145
00146
00147
00148
00149
00150
00151
00152
00180 int
00181 G_get_ellipsoid_by_name (const char *name, double *a, double *e2)
00182 {
00183 int i;
00184
00185 (void) read_ellipsoid_table(0);
00186
00187 for (i = 0; i < count; i++)
00188 {
00189 if (G_strcasecmp(name, table[i].name) == 0)
00190 {
00191 *a = table[i].a;
00192 *e2 = table[i].e2;
00193 return 1;
00194 }
00195 }
00196 return 0;
00197 }
00198
00199
00200
00201
00202
00203
00204
00205
00256 char *
00257 G_ellipsoid_name (int n)
00258 {
00259 (void) read_ellipsoid_table(0);
00260 return n>=0 && n < count ? table[n].name : NULL;
00261 }
00262
00263
00264
00265
00266
00267
00268
00269
00270
00271
00272
00273
00289 int
00290 G_get_spheroid_by_name(const char *name, double *a, double *e2, double *f)
00291 {
00292 int i;
00293
00294 (void) read_ellipsoid_table(0);
00295
00296 for (i = 0; i < count; i++)
00297 {
00298 if (G_strcasecmp(name, table[i].name) == 0)
00299 {
00300 *a = table[i].a;
00301 *e2 = table[i].e2;
00302 *f = table[i].f;
00303 return 1;
00304 }
00305 }
00306 return 0;
00307 }
00308
00309
00322 char *
00323 G_ellipsoid_description(int n)
00324 {
00325 (void) read_ellipsoid_table(0);
00326 return n>=0 && n < count ? table[n].descr : NULL;
00327 }
00328
00329 static int
00330 get_a_e2_f (const char *s1, const char *s2, double *a, double *e2, double *f)
00331 {
00332 double b, recipf;
00333
00334 if (sscanf (s1, "a=%lf", a) != 1)
00335 return 0;
00336
00337 if (*a <= 0.0)
00338 return 0;
00339
00340 if (sscanf (s2, "e=%lf", e2) == 1)
00341 {
00342 *f = (double)1.0 / - sqrt( ((double)1.0 - *e2) ) + (double)1.0;
00343 return (*e2 >= 0.0);
00344 }
00345
00346 if (sscanf (s2, "f=1/%lf", f) == 1)
00347 {
00348 if (*f <= 0.0)
00349 return 0;
00350 recipf = (double)1.0/(*f);
00351 *e2 = recipf + recipf - recipf * recipf;
00352 return (*e2 >= 0.0);
00353 }
00354
00355 if (sscanf (s2, "b=%lf", &b) == 1)
00356 {
00357 if (b <= 0.0) return 0;
00358 if (b == *a) {
00359 *f = 0.0;
00360 *e2 = 0.0;
00361 } else {
00362 recipf = ((*a) - b) / (*a);
00363 *f = (double)1.0 / recipf;
00364 *e2 = recipf + recipf - recipf * recipf;
00365 }
00366 return (*e2 >= 0.0);
00367 }
00368 return 0;
00369 }
00370
00371 void ellipsoid_table_file(char *file)
00372 {
00373 sprintf (file, "%s/etc/ellipse.table", G_gisbase());
00374 return;
00375 }
00376
00377 static int
00378 compare_table_names(const struct table *a, const struct table *b)
00379 {
00380
00381 return G_strcasecmp(a->name, b->name);
00382 }
00383
00384 static int
00385 read_ellipsoid_table(int fatal)
00386 {
00387 FILE *fd;
00388 char file[1024];
00389 char buf[1024];
00390 char name[100], descr[100], buf1[100], buf2[100];
00391 char badlines[256];
00392 int line;
00393 int err;
00394
00395 if (count >= 0)
00396 return 1;
00397 count = 0;
00398 table = NULL;
00399
00400 (void) ellipsoid_table_file (file);
00401 fd = fopen (file, "r");
00402
00403 if (fd == NULL)
00404 {
00405 perror (file);
00406 sprintf (buf, _("unable to open ellipsoid table file: %s"), file);
00407 fatal ? G_fatal_error(buf) : G_warning (buf);
00408 return 0;
00409 }
00410
00411 err = 0;
00412 *badlines = 0;
00413 for (line = 1; G_getl (buf, sizeof buf, fd); line++)
00414 {
00415 G_strip (buf);
00416 if (*buf == 0 || *buf == '#')
00417 continue;
00418
00419 if (sscanf (buf, "%s \"%99[^\"]\" %s %s", name, descr, buf1, buf2) != 4)
00420 {
00421 err++;
00422 sprintf (buf, " %d", line);
00423 if (*badlines)
00424 G_strcat(badlines, ",");
00425 G_strcat(badlines, buf);
00426 continue;
00427 }
00428
00429 table = (struct table *) G_realloc ((char *) table, (count+1) * sizeof(*table));
00430 table[count].name = G_store (name);
00431 table[count].descr = G_store (descr);
00432
00433 if(get_a_e2_f (buf1, buf2, &table[count].a, &table[count].e2, &table[count].f)
00434 || get_a_e2_f (buf2, buf1, &table[count].a, &table[count].e2, &table[count].f))
00435 count++;
00436 else
00437 {
00438 err++;
00439 sprintf (buf, " %d", line);
00440 if (*badlines)
00441 G_strcat (badlines, ",");
00442 G_strcat (badlines, buf);
00443 continue;
00444 }
00445 }
00446 if (!err)
00447 {
00448
00449 qsort ((void *)table, (size_t)count, (size_t)sizeof(*table), (int (*)(const void*, const void *))(compare_table_names));
00450 return 1;
00451 }
00452
00453 (fatal ? G_fatal_error : G_warning)(
00454 (err > 1)
00455 ? _("Lines %s of ellipsoid table file <%s> are invalid")
00456 : _("Line %s of ellipsoid table file <%s> is invalid"),
00457 badlines, file);
00458
00459 return 0;
00460 }