get_ellipse.c

Go to the documentation of this file.
00001 #include "gis.h"
00002 #include "glocale.h"
00003 #include <unistd.h>
00004 #include <ctype.h>
00005 #include <string.h>
00006 #include <stdlib.h>
00007 #include <math.h>  /* for sqrt() */
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 /* static int get_a_e2 (char *, char *, double *,double *); */
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  * This routine returns the ellipsoid parameters from the database.
00028  * If the PROJECTION_FILE exists in the PERMANENT mapset, read info from
00029  * that file, otherwise return WGS 84 values.
00030  *
00031  * Returns: 1 ok, 0 default values used.
00032  * Dies with diagnostic if there is an error
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     /* whats that? al 05/2000 */
00141     return 0;
00142 }
00143 
00144 /*
00145  * looks up ellipsoid in ellipsoid table and returns the
00146  * a, e2 parameters for the ellipsoid
00147  *
00148  * returns 1 if ok,
00149  *         0 if not found in table
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  * returns name(s) of ellipsoid
00201  *
00202  * for (i = 0; name = G_ellipsoid_name(i); i++)
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  * new 05/2000 by al: for datum shift the f parameter is needed too.
00265  * this all is not a clean design, but it keeps backward-
00266  * compatibility. 
00267  * looks up ellipsoid in ellipsoid table and returns the
00268  * a, e2 and f parameters for the ellipsoid
00269  * 
00270  * returns 1 if ok,
00271  *         0 if not found in table 
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   /* return strcmp(a->name,b->name); */
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         /* over correct typed version */
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 }

Generated on Sat Jul 22 22:06:14 2006 for GRASS by  doxygen 1.4.7