GRASS Programmer's Manual  6.5.svn(2014)-r66266
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
ellipse.c
Go to the documentation of this file.
1 
16 #include <unistd.h>
17 #include <ctype.h>
18 #include <string.h>
19 #include <stdlib.h>
20 #include <math.h> /* for sqrt() */
21 #include <grass/gis.h>
22 #include <grass/glocale.h>
23 #include <grass/gprojects.h>
24 #include "local_proto.h"
25 
26 static int get_a_e2_rf(const char *, const char *, double *, double *,
27  double *);
28 
37 int GPJ_get_ellipsoid_params(double *a, double *e2, double *rf)
38 {
39  int ret;
40  struct Key_Value *proj_keys = G_get_projinfo();
41 
42  if (proj_keys == NULL)
43  proj_keys = G_create_key_value();
44 
45  ret = GPJ__get_ellipsoid_params(proj_keys, a, e2, rf);
46  G_free_key_value(proj_keys);
47 
48  return ret;
49 }
50 
51 int
52 GPJ__get_ellipsoid_params(struct Key_Value *proj_keys,
53  double *a, double *e2, double *rf)
54 {
55  struct gpj_ellps estruct;
56  struct gpj_datum dstruct;
57  char *str, *str1, *str3;
58 
59  str = G_find_key_value("datum", proj_keys);
60 
61  if ((str != NULL) && (GPJ_get_datum_by_name(str, &dstruct) > 0)) {
62  /* If 'datum' key is present, look up correct ellipsoid
63  * from datum.table */
64 
65  str = G_store(dstruct.ellps);
66  GPJ_free_datum(&dstruct);
67 
68  }
69  else
70  /* else use ellipsoid defined in PROJ_INFO */
71  str = G_find_key_value("ellps", proj_keys);
72 
73  if (str != NULL) {
74  if (GPJ_get_ellipsoid_by_name(str, &estruct) < 0) {
75  G_fatal_error(_("Invalid ellipsoid <%s> in file"), str);
76  }
77  else {
78  *a = estruct.a;
79  *e2 = estruct.es;
80  *rf = estruct.rf;
81  GPJ_free_ellps(&estruct);
82  return 1;
83  }
84  }
85  else {
86  str3 = G_find_key_value("a", proj_keys);
87  if (str3 != NULL) {
88  G_asprintf(&str, "a=%s", str3);
89  if ((str3 = G_find_key_value("es", proj_keys)) != NULL)
90  G_asprintf(&str1, "e=%s", str3);
91  else if ((str3 = G_find_key_value("f", proj_keys)) != NULL)
92  G_asprintf(&str1, "f=1/%s", str3);
93  else if ((str3 = G_find_key_value("rf", proj_keys)) != NULL)
94  G_asprintf(&str1, "f=1/%s", str3);
95  else if ((str3 = G_find_key_value("b", proj_keys)) != NULL)
96  G_asprintf(&str1, "b=%s", str3);
97  else
98  G_fatal_error(_("No secondary ellipsoid descriptor "
99  "(rf, es or b) in file"));
100 
101  if (get_a_e2_rf(str, str1, a, e2, rf) == 0)
102  G_fatal_error(_("Invalid ellipsoid descriptors "
103  "(a, rf, es or b) in file"));
104  return 1;
105  }
106  else {
107  str = G_find_key_value("proj", proj_keys);
108  if ((str == NULL) || (strcmp(str, "ll") == 0)) {
109  *a = 6378137.0;
110  *e2 = .006694385;
111  *rf = 298.257223563;
112  return 0;
113  }
114  else {
115  G_fatal_error(_("No ellipsoid info given in file"));
116  }
117  }
118  }
119  return 1;
120 }
121 
122 
131 int GPJ_get_ellipsoid_by_name(const char *name, struct gpj_ellps *estruct)
132 {
133  struct ellps_list *list, *listhead;
134 
135  list = listhead = read_ellipsoid_table(0);
136 
137  while (list != NULL) {
138  if (G_strcasecmp(name, list->name) == 0) {
139  estruct->name = G_store(list->name);
140  estruct->longname = G_store(list->longname);
141  estruct->a = list->a;
142  estruct->es = list->es;
143  estruct->rf = list->rf;
144  free_ellps_list(listhead);
145  return 1;
146  }
147  list = list->next;
148  }
149  free_ellps_list(listhead);
150  return -1;
151 }
152 
153 static int
154 get_a_e2_rf(const char *s1, const char *s2, double *a, double *e2,
155  double *recipf)
156 {
157  double b, f;
158 
159  if (sscanf(s1, "a=%lf", a) != 1)
160  return 0;
161 
162  if (*a <= 0.0)
163  return 0;
164 
165  if (sscanf(s2, "e=%lf", e2) == 1) {
166  f = 1.0 - sqrt(1.0 - *e2);
167  *recipf = 1.0 / f;
168  return (*e2 >= 0.0);
169  }
170 
171  if (sscanf(s2, "f=1/%lf", recipf) == 1) {
172  if (*recipf <= 0.0)
173  return 0;
174  f = 1.0 / *recipf;
175  *e2 = f * (2 - f);
176  return (*e2 >= 0.0);
177  }
178 
179  if (sscanf(s2, "b=%lf", &b) == 1) {
180  if (b <= 0.0)
181  return 0;
182  if (b == *a) {
183  f = 0.0;
184  *e2 = 0.0;
185  }
186  else {
187  f = (*a - b) / *a;
188  *e2 = f * (2 - f);
189  }
190  *recipf = 1.0 / f;
191  return (*e2 >= 0.0);
192  }
193  return 0;
194 }
195 
197 {
198  FILE *fd;
199  char file[GPATH_MAX];
200  char buf[4096];
201  char name[100], descr[1024], buf1[1024], buf2[1024];
202  char badlines[1024];
203  int line;
204  int err;
205  struct ellps_list *current = NULL, *outputlist = NULL;
206  double a, e2, rf;
207 
208  int count = 0;
209 
210  sprintf(file, "%s%s", G_gisbase(), ELLIPSOIDTABLE);
211  fd = fopen(file, "r");
212 
213  if (!fd) {
214  (fatal ? G_fatal_error : G_warning)(
215  _("Unable to open ellipsoid table file <%s>"), file);
216  return NULL;
217  }
218 
219  err = 0;
220  *badlines = 0;
221  for (line = 1; G_getl2(buf, sizeof buf, fd); line++) {
222  G_strip(buf);
223  if (*buf == 0 || *buf == '#')
224  continue;
225 
226  if (sscanf(buf, "%s \"%1023[^\"]\" %s %s", name, descr, buf1, buf2)
227  != 4) {
228  err++;
229  sprintf(buf, " %d", line);
230  if (*badlines)
231  G_strcat(badlines, ",");
232  G_strcat(badlines, buf);
233  continue;
234  }
235 
236 
237  if (get_a_e2_rf(buf1, buf2, &a, &e2, &rf)
238  || get_a_e2_rf(buf2, buf1, &a, &e2, &rf)) {
239  if (current == NULL)
240  current = outputlist = G_malloc(sizeof(struct ellps_list));
241  else
242  current = current->next = G_malloc(sizeof(struct ellps_list));
243  current->name = G_store(name);
244  current->longname = G_store(descr);
245  current->a = a;
246  current->es = e2;
247  current->rf = rf;
248  current->next = NULL;
249  count++;
250  }
251  else {
252  err++;
253  sprintf(buf, " %d", line);
254  if (*badlines)
255  G_strcat(badlines, ",");
256  G_strcat(badlines, buf);
257  continue;
258  }
259  }
260 
261  fclose(fd);
262 
263  if (!err)
264  return outputlist;
265 
266  (fatal ? G_fatal_error : G_warning)(
267  err == 1
268  ? _("Line%s of ellipsoid table file <%s> is invalid")
269  : _("Lines%s of ellipsoid table file <%s> are invalid"),
270  badlines, file);
271 
272  return outputlist;
273 }
274 
275 void GPJ_free_ellps(struct gpj_ellps *estruct)
276 {
277  G_free(estruct->name);
278  G_free(estruct->longname);
279  return;
280 }
281 
282 void free_ellps_list(struct ellps_list *elist)
283 {
284  struct ellps_list *old;
285 
286  while (elist != NULL) {
287  G_free(elist->name);
288  G_free(elist->longname);
289  old = elist;
290  elist = old->next;
291  G_free(old);
292  }
293 
294  return;
295 }
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)
void G_free(void *buf)
Free allocated memory.
Definition: gis/alloc.c:142
void GPJ_free_datum(struct gpj_datum *dstruct)
Free the memory used for the strings in a gpj_datum struct.
Definition: proj/datum.c:543
float b
Definition: named_colr.c:8
char * G_store(const char *s)
Copy string to allocated memory.
Definition: store.c:32
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
struct ellps_list * read_ellipsoid_table(int fatal)
Definition: ellipse.c:196
int G_free_key_value(struct Key_Value *kv)
Free allocated Key_Value structure.
Definition: key_value1.c:145
int count
const char * err
Definition: g3dcolor.c:50
int G_asprintf(char **out, const char *fmt,...)
Definition: asprintf.c:116
int GPJ_get_datum_by_name(const char *name, struct gpj_datum *dstruct)
Look up a string in datum.table file to see if it is a valid datum name and if so place its informati...
Definition: proj/datum.c:37
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 GPJ__get_ellipsoid_params(struct Key_Value *proj_keys, double *a, double *e2, double *rf)
Definition: ellipse.c:52
void GPJ_free_ellps(struct gpj_ellps *estruct)
Definition: ellipse.c:275
int G_strip(char *buf)
Removes all leading and trailing white space from string.
Definition: strings.c:389
struct Key_Value * G_get_projinfo(void)
Gets projection information for location.
Definition: get_projinfo.c:52
struct ellps_list * next
char buf[GNAME_MAX+sizeof(G3D_DIRECTORY)+2]
Definition: g3drange.c:62
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 GPJ_get_ellipsoid_params(double *a, double *e2, double *rf)
Definition: ellipse.c:37
int old
Definition: g3dcats.c:92
int G_fatal_error(const char *msg,...)
Print a fatal error message to stderr.
int GPJ_get_ellipsoid_by_name(const char *name, struct gpj_ellps *estruct)
looks up ellipsoid in ellipsoid table and returns the a, e2 parameters for the ellipsoid ...
Definition: ellipse.c:131
struct Key_Value * G_create_key_value(void)
Allocate and initialize Key_Value structure.
Definition: key_value1.c:25
void free_ellps_list(struct ellps_list *elist)
Definition: ellipse.c:282