1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
|
/* projection initialization and closure */
#ifndef lint
static const char SCCSID[]="@(#)pj_init.c 4.13 95/09/05 GIE REL";
#endif
#define PJ_LIB__
#include <projects.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>
static paralist
*start;
extern FILE *pj_open_lib(char *, char *);
static paralist *
get_opt(FILE *fid, char *name, paralist *next) {
char sword[52], *word = sword+1;
int first = 1, len, c;
len = strlen(name);
*sword = 't';
while (fscanf(fid, "%50s", word) == 1)
if (*word == '#') /* skip comments */
while((c = fgetc(fid)) != EOF && c != '\n') ;
else if (*word == '<') { /* control name */
if (first && !strncmp(name, word + 1, len)
&& word[len + 1] == '>')
first = 0;
else if (!first && word[1] == '>')
break;
} else if (!first && !pj_param(start, sword).i)
next = next->next = pj_mkparam(word);
if (errno == 25)
errno = 0;
return next;
}
static paralist *
get_defaults(paralist *next, char *name) {
FILE *fid;
if (fid = pj_open_lib("proj_def.dat", "r")) {
next = get_opt(fid, "general", next);
rewind(fid);
next = get_opt(fid, name, next);
(void)fclose(fid);
}
if (errno)
errno = 0; /* don't care if can't open file */
return next;
}
static paralist *
get_init(paralist *next, char *name) {
char fname[MAX_PATH_FILENAME+ID_TAG_MAX+3], *opt;
FILE *fid;
(void)strncpy(fname, name, MAX_PATH_FILENAME + ID_TAG_MAX + 1);
if (opt = strrchr(fname, ':'))
*opt++ = '\0';
else { pj_errno = -3; return(0); }
if (fid = pj_open_lib(fname, "r"))
next = get_opt(fid, opt, next);
else
return(0);
(void)fclose(fid);
if (errno == 25)
errno = 0; /* unknown problem with some sys errno<-25 */
return next;
}
PJ *
pj_init(int argc, char **argv) {
char *s, *name;
void *(*proj)(PJ *);
paralist *curr;
int i;
PJ *PIN = 0;
errno = pj_errno = 0;
/* put arguments into internal linked list */
if (argc <= 0) { pj_errno = -1; goto bum_call; }
for (i = 0; i < argc; ++i)
if (i)
curr = curr->next = pj_mkparam(argv[i]);
else
start = curr = pj_mkparam(argv[i]);
if (pj_errno) goto bum_call;
/* check if +init present */
if (pj_param(start, "tinit").i) {
paralist *last = curr;
if (!(curr = get_init(curr, pj_param(start, "sinit").s)))
goto bum_call;
if (curr == last) { pj_errno = -2; goto bum_call; }
}
/* find projection selection */
if (!(name = pj_param(start, "sproj").s))
{ pj_errno = -4; goto bum_call; }
for (i = 0; (s = pj_list[i].id) && strcmp(name, s) ; ++i) ;
if (!s) { pj_errno = -5; goto bum_call; }
/* set defaults, unless inhibited */
if (!pj_param(start, "bno_defs").i)
curr = get_defaults(curr, name);
proj = pj_list[i].proj;
/* allocate projection structure */
if (!(PIN = (*proj)(0))) goto bum_call;
PIN->params = start;
/* set ellipsoid/sphere parameters */
if (pj_ell_set(start, &PIN->a, &PIN->es)) goto bum_call;
PIN->e = sqrt(PIN->es);
PIN->ra = 1. / PIN->a;
PIN->one_es = 1. - PIN->es;
if (PIN->one_es == 0.) { pj_errno = -6; goto bum_call; }
PIN->rone_es = 1./PIN->one_es;
/* set PIN->geoc coordinate system */
PIN->geoc = (PIN->es && pj_param(start, "bgeoc").i);
/* over-ranging flag */
PIN->over = pj_param(start, "bover").i;
/* central meridian */
PIN->lam0=pj_param(start, "rlon_0").f;
/* central latitude */
PIN->phi0 = pj_param(start, "rlat_0").f;
/* false easting and northing */
PIN->x0 = pj_param(start, "dx_0").f;
PIN->y0 = pj_param(start, "dy_0").f;
/* general scaling factor */
if (pj_param(start, "tk_0").i)
PIN->k0 = pj_param(start, "dk_0").f;
else if (pj_param(start, "tk").i)
PIN->k0 = pj_param(start, "dk").f;
else
PIN->k0 = 1.;
if (PIN->k0 <= 0.) {
pj_errno = -31;
goto bum_call;
}
/* set units */
s = 0;
if (name = pj_param(start, "sunits").s) {
for (i = 0; (s = pj_units[i].id) && strcmp(name, s) ; ++i) ;
if (!s) { pj_errno = -7; goto bum_call; }
s = pj_units[i].to_meter;
}
if (s || (s = pj_param(start, "sto_meter").s)) {
PIN->to_meter = strtod(s, &s);
if (*s == '/') /* ratio number */
PIN->to_meter /= strtod(++s, 0);
PIN->fr_meter = 1. / PIN->to_meter;
} else
PIN->to_meter = PIN->fr_meter = 1.;
/* projection specific initialization */
if (!(PIN = (*proj)(PIN)) || errno || pj_errno) {
bum_call: /* cleanup error return */
if (!pj_errno)
pj_errno = errno;
if (PIN)
pj_free(PIN);
else
for ( ; start; start = curr) {
curr = start->next;
pj_dalloc(start);
}
PIN = 0;
}
return PIN;
}
void
pj_free(PJ *P) {
if (P) {
paralist *t = P->params, *n;
/* free parameter list elements */
for (t = P->params; t; t = n) {
n = t->next;
pj_dalloc(t);
}
/* free projection parameters */
P->pfree(P);
}
}
|