GRASS Programmer's Manual  6.5.svn(2014)-r66266
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
get_ellipse.c
Go to the documentation of this file.
1 
23 #include <unistd.h>
24 #include <ctype.h>
25 #include <string.h>
26 #include <stdlib.h>
27 #include <math.h> /* for sqrt() */
28 #include <grass/gis.h>
29 #include <grass/glocale.h>
30 
31 static struct table
32 {
33  char *name;
34  char *descr;
35  double a;
36  double e2;
37  double f;
38 } *table = NULL;
39 
40 static int count = -1;
41 static char *PERMANENT = "PERMANENT";
42 
43 /* static int get_a_e2 (char *, char *, double *,double *); */
44 static int get_a_e2_f(const char *, const char *, double *, double *,
45  double *);
46 void ellipsoid_table_file(char *);
47 static int compare_table_names(const void *, const void *);
48 static int read_ellipsoid_table(int);
49 static int get_ellipsoid_parameters(struct Key_Value *, double *, double *);
50 
51 
66 int G_get_ellipsoid_parameters(double *a, double *e2)
67 {
68  int in_stat, stat;
69  char ipath[GPATH_MAX];
70  struct Key_Value *proj_keys;
71 
72  proj_keys = NULL;
73 
74  G__file_name(ipath, "", PROJECTION_FILE, PERMANENT);
75 
76  if (access(ipath, 0) != 0) {
77  *a = 6378137.0;
78  *e2 = .006694385;
79  return 0;
80  }
81 
82  proj_keys = G_read_key_value_file(ipath, &in_stat);
83 
84  if (in_stat != 0) {
85  G_fatal_error(_("Unable to open file %s in <%s>"),
86  PROJECTION_FILE, PERMANENT);
87  }
88 
89  stat = get_ellipsoid_parameters(proj_keys, a, e2);
90 
91  G_free_key_value(proj_keys);
92 
93  return stat;
94 }
95 
110 int G_get_ellipsoid_by_name(const char *name, double *a, double *e2)
111 {
112  int i;
113 
114  (void)read_ellipsoid_table(0);
115 
116  for (i = 0; i < count; i++) {
117  if (G_strcasecmp(name, table[i].name) == 0) {
118  *a = table[i].a;
119  *e2 = table[i].e2;
120  return 1;
121  }
122  }
123  return 0;
124 }
125 
138 char *G_ellipsoid_name(int n)
139 {
140  (void)read_ellipsoid_table(0);
141  return n >= 0 && n < count ? table[n].name : NULL;
142 }
143 
144 /*
145  * new 05/2000 by al: for datum shift the f parameter is needed too.
146  * this all is not a clean design, but it keeps backward-
147  * compatibility.
148  * looks up ellipsoid in ellipsoid table and returns the
149  * a, e2 and f parameters for the ellipsoid
150  *
151  * returns 1 if ok,
152  * 0 if not found in table
153  */
154 
171 int G_get_spheroid_by_name(const char *name, double *a, double *e2, double *f)
172 {
173  int i;
174 
175  (void)read_ellipsoid_table(0);
176 
177  for (i = 0; i < count; i++) {
178  if (G_strcasecmp(name, table[i].name) == 0) {
179  *a = table[i].a;
180  *e2 = table[i].e2;
181  *f = table[i].f;
182  return 1;
183  }
184  }
185  return 0;
186 }
187 
188 
203 {
204  (void)read_ellipsoid_table(0);
205  return n >= 0 && n < count ? table[n].descr : NULL;
206 }
207 
208 static int
209 get_a_e2_f(const char *s1, const char *s2, double *a, double *e2, double *f)
210 {
211  double b, recipf;
212 
213  if (sscanf(s1, "a=%lf", a) != 1)
214  return 0;
215 
216  if (*a <= 0.0)
217  return 0;
218 
219  if (sscanf(s2, "e=%lf", e2) == 1) {
220  *f = (double)1.0 / -sqrt(((double)1.0 - *e2)) + (double)1.0;
221  return (*e2 >= 0.0);
222  }
223 
224  if (sscanf(s2, "f=1/%lf", f) == 1) {
225  if (*f <= 0.0)
226  return 0;
227  recipf = (double)1.0 / (*f);
228  *e2 = recipf + recipf - recipf * recipf;
229  return (*e2 >= 0.0);
230  }
231 
232  if (sscanf(s2, "b=%lf", &b) == 1) {
233  if (b <= 0.0)
234  return 0;
235  if (b == *a) {
236  *f = 0.0;
237  *e2 = 0.0;
238  }
239  else {
240  recipf = ((*a) - b) / (*a);
241  *f = (double)1.0 / recipf;
242  *e2 = recipf + recipf - recipf * recipf;
243  }
244  return (*e2 >= 0.0);
245  }
246  return 0;
247 }
248 
250 {
251  sprintf(file, "%s/etc/ellipse.table", G_gisbase());
252  return;
253 }
254 
255 static int compare_table_names(const void *pa, const void *pb)
256 {
257  const struct table *a = pa, *b = pb;
258 
259  /* return strcmp(a->name,b->name); */
260  return G_strcasecmp(a->name, b->name);
261 }
262 
263 static int read_ellipsoid_table(int fatal)
264 {
265  FILE *fd;
266  char file[GPATH_MAX];
267  char buf[1024];
268  char name[100], descr[100], buf1[100], buf2[100];
269  char badlines[256];
270  int line;
271  int err;
272 
273  if (count >= 0)
274  return 1;
275  count = 0;
276  table = NULL;
277 
278  (void)ellipsoid_table_file(file);
279  fd = fopen(file, "r");
280 
281  if (fd == NULL) {
282  perror(file);
283  sprintf(buf, _("Unable to open ellipsoid table file <%s>"), file);
284  fatal ? G_fatal_error(buf) : G_warning(buf);
285  return 0;
286  }
287 
288  err = 0;
289  *badlines = 0;
290  for (line = 1; G_getl2(buf, sizeof buf, fd); line++) {
291  G_strip(buf);
292  if (*buf == 0 || *buf == '#')
293  continue;
294 
295  if (sscanf(buf, "%s \"%99[^\"]\" %s %s", name, descr, buf1, buf2) !=
296  4) {
297  err++;
298  sprintf(buf, " %d", line);
299  if (*badlines)
300  G_strcat(badlines, ",");
301  G_strcat(badlines, buf);
302  continue;
303  }
304 
305  table =
306  (struct table *)G_realloc((char *)table,
307  (count + 1) * sizeof(*table));
308  table[count].name = G_store(name);
309  table[count].descr = G_store(descr);
310 
311  if (get_a_e2_f
312  (buf1, buf2, &table[count].a, &table[count].e2, &table[count].f)
313  || get_a_e2_f(buf2, buf1, &table[count].a, &table[count].e2,
314  &table[count].f))
315  count++;
316  else {
317  err++;
318  sprintf(buf, " %d", line);
319  if (*badlines)
320  G_strcat(badlines, ",");
321  G_strcat(badlines, buf);
322  continue;
323  }
324  }
325 
326  fclose(fd);
327 
328  if (!err) {
329  /* over correct typed version */
330  qsort(table, count, sizeof(*table), compare_table_names);
331  return 1;
332  }
333 
334  (fatal ? G_fatal_error : G_warning) ((err > 1)
335  ?
336  _("Lines%s of ellipsoid table file <%s> are invalid")
337  :
338  _("Line%s of ellipsoid table file <%s> is invalid"),
339  badlines, file);
340 
341  return 0;
342 }
343 
344 static int get_ellipsoid_parameters(struct Key_Value *proj_keys, double *a,
345  double *e2)
346 {
347  char *str, *str1;
348 
349  if (!proj_keys) {
350  return -1;
351  }
352 
353  if ((str = G_find_key_value("ellps", proj_keys)) != NULL) {
354  if (strncmp(str, "sphere", 6) == 0) {
355  str = G_find_key_value("a", proj_keys);
356  if (str != NULL) {
357  if (sscanf(str, "%lf", a) != 1) {
358  G_fatal_error(_("Invalid a: field '%s' in file %s in <%s>"),
359  str, PROJECTION_FILE, PERMANENT);
360  }
361  }
362  else {
363  *a = 6370997.0;
364  }
365  *e2 = 0.0;
366 
367  return 0;
368  }
369  else {
370  if (G_get_ellipsoid_by_name(str, a, e2) == 0) {
371  G_fatal_error(_("Invalid ellipsoid '%s' in file %s in <%s>"),
372  str, PROJECTION_FILE, PERMANENT);
373  }
374  else {
375  return 1;
376  }
377  }
378  }
379  else {
380  str = G_find_key_value("a", proj_keys);
381  str1 = G_find_key_value("es", proj_keys);
382  if ((str != NULL) && (str1 != NULL)) {
383  if (sscanf(str, "%lf", a) != 1) {
384  G_fatal_error(_("Invalid a: field '%s' in file %s in <%s>"),
385  str, PROJECTION_FILE, PERMANENT);
386  }
387  if (sscanf(str1, "%lf", e2) != 1) {
388  G_fatal_error(_("Invalid es: field '%s' in file %s in <%s>"),
389  str, PROJECTION_FILE, PERMANENT);
390  }
391 
392  return 1;
393  }
394  else {
395  str = G_find_key_value("proj", proj_keys);
396  if ((str == NULL) || (strcmp(str, "ll") == 0)) {
397  *a = 6378137.0;
398  *e2 = .006694385;
399  return 0;
400  }
401  else {
402  G_fatal_error(_("No ellipsoid info given in file %s in <%s>"),
403  PROJECTION_FILE, PERMANENT);
404  }
405  }
406  }
407 
408  return 1;
409 }
char * G_find_key_value(const char *key, const struct Key_Value *kv)
Find given key.
Definition: key_value1.c:128
int G_strcasecmp(const char *x, const char *y)
String compare ignoring case (upper or lower)
Definition: strings.c:192
sprintf(buf2,"%s", G3D_CATS_ELEMENT)
#define PERMANENT
Definition: get_projinfo.c:18
float b
Definition: named_colr.c:8
char * G_store(const char *s)
Copy string to allocated memory.
Definition: store.c:32
void ellipsoid_table_file(char *)
Definition: get_ellipse.c:249
char * G_strcat(char *T, const char *F)
This copies characters from the string F into the string T.
Definition: strings.c:153
FILE * fd
Definition: g3dcolor.c:368
string name
Definition: render.py:1314
int G_free_key_value(struct Key_Value *kv)
Free allocated Key_Value structure.
Definition: key_value1.c:145
int count
int G_get_ellipsoid_parameters(double *a, double *e2)
get ellipsoid parameters
Definition: get_ellipse.c:66
const char * err
Definition: g3dcolor.c:50
int G_getl2(char *buf, int n, FILE *fd)
gets a line of text from a file of any pedigree
Definition: getl.c:52
def fatal
Display an error message using g.message -e, then abort.
Definition: core.py:383
int stat
Definition: g3dcolor.c:369
char * G__file_name(char *path, const char *element, const char *name, const char *mapset)
Builds full path names to GIS data files.
Definition: file_name.c:33
struct Key_Value * G_read_key_value_file(const char *file, int *stat)
Read key/values pairs from file.
Definition: key_value3.c:54
int G_strip(char *buf)
Removes all leading and trailing white space from string.
Definition: strings.c:389
char * G_ellipsoid_description(int n)
get description for nth ellipsoid
Definition: get_ellipse.c:202
char * G_ellipsoid_name(int n)
get ellipsoid name
Definition: get_ellipse.c:138
int G_get_ellipsoid_by_name(const char *name, double *a, double *e2)
get ellipsoid parameters by name
Definition: get_ellipse.c:110
char buf[GNAME_MAX+sizeof(G3D_DIRECTORY)+2]
Definition: g3drange.c:62
int G_get_spheroid_by_name(const char *name, double *a, double *e2, double *f)
get spheroid parameters by name
Definition: get_ellipse.c:171
return NULL
Definition: dbfopen.c:1394
G_warning("category support for [%s] in mapset [%s] %s", name, mapset, type)
fclose(fd)
char buf2[200]
Definition: g3dcats.c:89
#define file
char * G_gisbase(void)
top level module directory
Definition: gisbase.c:42
int G_fatal_error(const char *msg,...)
Print a fatal error message to stderr.
int n
Definition: dataquad.c:291