GRASS 8 Programmer's Manual 8.6.0dev(2026)-1878fdfec5
Loading...
Searching...
No Matches
ellipse.c
Go to the documentation of this file.
1/*!
2 \file lib/proj/ellipse.c
3
4 \brief GProj library - Functions for reading datum parameters from the
5 location database
6
7 \author Paul Kelly <paul-grass stjohnspoint.co.uk>
8
9 SPDX-FileCopyrightText: 2003-2008 GRASS Development Team
10 SPDX-License-Identifier: GPL-2.0-or-later
11 */
12
13#include <unistd.h>
14#include <ctype.h>
15#include <string.h>
16#include <stdlib.h>
17#include <math.h> /* for sqrt() */
18#include <grass/gis.h>
19#include <grass/glocale.h>
20#include <grass/gprojects.h>
21#include "local_proto.h"
22
23static int get_a_e2_rf(const char *, const char *, double *, double *,
24 double *);
25
26/*!
27 * \brief Get the ellipsoid parameters from the database.
28 *
29 * If the PROJECTION_FILE exists in the PERMANENT mapset, read info from
30 * that file, otherwise return WGS 84 values.
31 *
32 * Dies with diagnostic if there is an error.
33 *
34 * \param[out] a semi-major axis
35 * \param[out] e2 first eccentricity squared
36 * \param[out] rf reciprocal of the ellipsoid flattening term
37 *
38 * \return 1 on success
39 * \return 0 default values used.
40 */
41int GPJ_get_ellipsoid_params(double *a, double *e2, double *rf)
42{
43 int ret;
45
46 if (proj_keys == NULL)
48
51
52 return ret;
53}
54
55/*!
56 * \brief Get the ellipsoid parameters from proj keys structure.
57 *
58 * If the PROJECTION_FILE exists in the PERMANENT mapset, read info from
59 * that file, otherwise return WGS 84 values.
60 *
61 * Dies with diagnostic if there is an error.
62 *
63 * \param proj_keys proj definition
64 * \param[out] a semi-major axis
65 * \param[out] e2 first eccentricity squared
66 * \param[out] rf reciprocal of the ellipsoid flattening term
67 *
68 * \return 1 on success
69 * \return 0 default values used.
70 */
71int GPJ__get_ellipsoid_params(const struct Key_Value *proj_keys, double *a,
72 double *e2, double *rf)
73{
74 struct gpj_ellps estruct;
75 struct gpj_datum dstruct;
76 const char *str, *str3;
77 char *str1, *ellps;
78
79 str = G_find_key_value("datum", proj_keys);
80
81 if ((str != NULL) && (GPJ_get_datum_by_name(str, &dstruct) > 0)) {
82 /* If 'datum' key is present, look up correct ellipsoid
83 * from datum.table */
84
85 ellps = G_store(dstruct.ellps);
87 }
88 else
89 /* else use ellipsoid defined in PROJ_INFO */
91
92 if (ellps != NULL && *ellps) {
94 G_fatal_error(_("Invalid ellipsoid <%s> in file"), ellps);
95
96 *a = estruct.a;
97 *e2 = estruct.es;
98 *rf = estruct.rf;
100 G_free(ellps);
101
102 return 1;
103 }
104 else {
105 if (ellps) /* *ellps = '\0' */
106 G_free(ellps);
107
109 if (str3 != NULL) {
110 char *str4;
111
112 G_asprintf(&str4, "a=%s", str3);
113 if ((str3 = G_find_key_value("es", proj_keys)) != NULL)
114 G_asprintf(&str1, "e=%s", str3);
115 else if ((str3 = G_find_key_value("f", proj_keys)) != NULL)
116 G_asprintf(&str1, "f=1/%s", str3);
117 else if ((str3 = G_find_key_value("rf", proj_keys)) != NULL)
118 G_asprintf(&str1, "f=1/%s", str3);
119 else if ((str3 = G_find_key_value("b", proj_keys)) != NULL)
120 G_asprintf(&str1, "b=%s", str3);
121 else
122 G_fatal_error(_("No secondary ellipsoid descriptor "
123 "(rf, es or b) in file"));
124
125 if (get_a_e2_rf(str4, str1, a, e2, rf) == 0)
126 G_fatal_error(_("Invalid ellipsoid descriptors "
127 "(a, rf, es or b) in file"));
128 return 1;
129 }
130 else {
131 str = G_find_key_value("proj", proj_keys);
132 if ((str == NULL) || (strcmp(str, "ll") == 0)) {
133 *a = 6378137.0;
134 *e2 = .006694385;
135 *rf = 298.257223563;
136 return 0;
137 }
138 else {
139 G_fatal_error(_("No ellipsoid info given in file"));
140 }
141 }
142 }
143 return 1;
144}
145
146/*!
147 * \brief Looks up ellipsoid in ellipsoid table and returns the a, e2
148 * parameters for the ellipsoid.
149 *
150 * \param name ellipsoid name
151 * \param[out] estruct ellipsoid
152 *
153 * \return 1 on success
154 * \return -1 if not found in table
155 */
157{
158 struct ellps_list *list, *listhead;
159
161
162 while (list != NULL) {
163 if (G_strcasecmp(name, list->name) == 0) {
164 estruct->name = G_store(list->name);
165 estruct->longname = G_store(list->longname);
166 estruct->a = list->a;
167 estruct->es = list->es;
168 estruct->rf = list->rf;
170 return 1;
171 }
172 list = list->next;
173 }
175 return -1;
176}
177
178int get_a_e2_rf(const char *s1, const char *s2, double *a, double *e2,
179 double *recipf)
180{
181 double b, f;
182
183 if (sscanf(s1, "a=%lf", a) != 1)
184 return 0;
185
186 if (*a <= 0.0)
187 return 0;
188
189 if (sscanf(s2, "e=%lf", e2) == 1) {
190 f = 1.0 - sqrt(1.0 - *e2);
191 *recipf = 1.0 / f;
192 return (*e2 >= 0.0);
193 }
194
195 if (sscanf(s2, "f=1/%lf", recipf) == 1) {
196 if (*recipf <= 0.0)
197 return 0;
198 f = 1.0 / *recipf;
199 *e2 = f * (2 - f);
200 return (*e2 >= 0.0);
201 }
202
203 if (sscanf(s2, "b=%lf", &b) == 1) {
204 if (b <= 0.0)
205 return 0;
206 if (b == *a) {
207 f = 0.0;
208 *e2 = 0.0;
209 }
210 else {
211 f = (*a - b) / *a;
212 *e2 = f * (2 - f);
213 }
214 *recipf = 1.0 / f;
215 return (*e2 >= 0.0);
216 }
217 return 0;
218}
219
221{
222 FILE *fd;
223 char file[GPATH_MAX];
224 char buf[4096];
225 char name[100], descr[1024], buf1[1024], buf2[1024];
226 char badlines[1024];
227 int line;
228 int err;
229 struct ellps_list *current = NULL, *outputlist = NULL;
230 double a, e2, rf;
231
232 snprintf(file, sizeof(file), "%s%s", G_gisbase(), ELLIPSOIDTABLE);
233 fd = fopen(file, "r");
234
235 if (!fd) {
237 _("Unable to open ellipsoid table file <%s>"), file);
238 return NULL;
239 }
240
241 err = 0;
242 *badlines = 0;
243 for (line = 1; G_getl2(buf, sizeof buf, fd); line++) {
244 G_strip(buf);
245 if (*buf == 0 || *buf == '#')
246 continue;
247
248 if (sscanf(buf, "%s \"%1023[^\"]\" %s %s", name, descr, buf1, buf2) !=
249 4) {
250 err++;
251 snprintf(buf, sizeof(buf), " %d", line);
252 if (*badlines)
253 strcat(badlines, ",");
255 continue;
256 }
257
258 if (get_a_e2_rf(buf1, buf2, &a, &e2, &rf) ||
259 get_a_e2_rf(buf2, buf1, &a, &e2, &rf)) {
260 if (current == NULL)
261 current = outputlist = G_malloc(sizeof(struct ellps_list));
262 else
263 current = current->next = G_malloc(sizeof(struct ellps_list));
264 current->name = G_store(name);
265 current->longname = G_store(descr);
266 current->a = a;
267 current->es = e2;
268 current->rf = rf;
269 current->next = NULL;
270 }
271 else {
272 err++;
273 snprintf(buf, sizeof(buf), " %d", line);
274 if (*badlines)
275 strcat(badlines, ",");
277 continue;
278 }
279 }
280
281 fclose(fd);
282
283 if (!err)
284 return outputlist;
285
287 n_(("Line%s of ellipsoid table file <%s> is invalid"),
288 ("Lines%s of ellipsoid table file <%s> are invalid"), err),
289 badlines, file);
290
291 return outputlist;
292}
293
294/*!
295 \brief Free ellipsoid data structure.
296
297 \param estruct data structure to be freed
298 */
300{
302 G_free(estruct->longname);
303 return;
304}
305
307{
308 struct ellps_list *old;
309
310 while (elist != NULL) {
311 G_free(elist->name);
312 G_free(elist->longname);
313 old = elist;
314 elist = old->next;
315 G_free(old);
316 }
317
318 return;
319}
#define NULL
Definition ccmath.h:32
AMI_err name(char **stream_name)
Definition ami_stream.h:426
int G_getl2(char *, int, FILE *)
Gets a line of text from a file of any pedigree.
Definition getl.c:58
void G_free(void *)
Free allocated memory.
Definition gis/alloc.c:145
struct Key_Value * G_get_projinfo(void)
Gets projection information for location.
void void void void G_fatal_error(const char *,...) __attribute__((format(printf
void G_warning(const char *,...) __attribute__((format(printf
const char * G_gisbase(void)
Get full path name of the top level module directory.
Definition gisbase.c:39
#define G_malloc(n)
Definition defs/gis.h:136
void G_free_key_value(struct Key_Value *)
Free allocated Key_Value structure.
Definition key_value1.c:102
void G_strip(char *)
Removes all leading and trailing white space from string.
Definition strings.c:298
int G_asprintf(char **, const char *,...) __attribute__((format(printf
struct Key_Value * G_create_key_value(void)
Allocate and initialize Key_Value structure.
Definition key_value1.c:21
const char * G_find_key_value(const char *, const struct Key_Value *)
Find given key (case sensitive)
Definition key_value1.c:83
int int G_strcasecmp(const char *, const char *)
String compare ignoring case (upper or lower)
Definition strings.c:45
char * G_store(const char *)
Copy string to allocated memory.
Definition strings.c:85
void GPJ_free_datum(struct gpj_datum *)
Free the memory used for the strings in a gpj_datum struct.
Definition proj/datum.c:393
int GPJ_get_datum_by_name(const char *, struct gpj_datum *)
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:35
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:156
struct ellps_list * read_ellipsoid_table(int fatal)
Definition ellipse.c:220
int GPJ__get_ellipsoid_params(const struct Key_Value *proj_keys, double *a, double *e2, double *rf)
Get the ellipsoid parameters from proj keys structure.
Definition ellipse.c:71
void free_ellps_list(struct ellps_list *elist)
Definition ellipse.c:306
void GPJ_free_ellps(struct gpj_ellps *estruct)
Free ellipsoid data structure.
Definition ellipse.c:299
int GPJ_get_ellipsoid_params(double *a, double *e2, double *rf)
Get the ellipsoid parameters from the database.
Definition ellipse.c:41
#define GPATH_MAX
Definition gis.h:196
#define n_(strs, strp, num)
Definition glocale.h:11
#define _(str)
Definition glocale.h:10
#define ELLIPSOIDTABLE
Definition gprojects.h:31
#define file
const char * name
Definition named_colr.c:6
double b
Definition r_raster.c:37
char * ellps
Definition gprojects.h:49
Definition manage.h:4
SYMBOL * err(FILE *fp, SYMBOL *s, char *msg)