-
-
Notifications
You must be signed in to change notification settings - Fork 288
/
datumtrans.c
233 lines (196 loc) · 6.76 KB
/
datumtrans.c
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
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
/*
****************************************************************************
*
* MODULE: g.proj
* AUTHOR(S): Paul Kelly - paul-grass@stjohnspoint.co.uk
* PURPOSE: Provides a means of reporting the contents of GRASS
* projection information files and creating
* new projection information files.
* COPYRIGHT: (C) 2007 by the GRASS Development Team
*
* This program is free software under the GNU General Public
* License (>=v2). Read the file COPYING that comes with GRASS
* for details.
*
*****************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <grass/gis.h>
#include <grass/glocale.h>
#include <grass/gprojects.h>
#include "local_proto.h"
/**
*
* \brief Add or replace datum to the current co-ordinate system definition
*
* \param datum Use this datum (overrides any datum found in the
* current co-ordinate system definition).
*
* \return 1 if a change was made, 0 if not.
**/
int set_datum(char *datum)
{
struct gpj_datum dstruct;
struct Key_Value *temp_projinfo;
int i;
if (cellhd.proj == PROJECTION_XY)
return 0;
if (!datum || GPJ_get_datum_by_name(datum, &dstruct) < 0)
{
G_fatal_error(_("Invalid datum code <%s>"), datum);
return 0;
}
temp_projinfo = G_create_key_value();
/* Copy old PROJ_INFO, skipping out any keys related
* to datum or ellipsoid parameters */
for (i = 0; i < projinfo->nitems; i++) {
if (strcmp(projinfo->key[i], "datum") == 0
|| strcmp(projinfo->key[i], "dx") == 0
|| strcmp(projinfo->key[i], "dy") == 0
|| strcmp(projinfo->key[i], "dz") == 0
|| strcmp(projinfo->key[i], "datumparams") == 0
|| strcmp(projinfo->key[i], "nadgrids") == 0
|| strcmp(projinfo->key[i], "towgs84") == 0
|| strcmp(projinfo->key[i], "ellps") == 0
|| strcmp(projinfo->key[i], "a") == 0
|| strcmp(projinfo->key[i], "b") == 0
|| strcmp(projinfo->key[i], "es") == 0
|| strcmp(projinfo->key[i], "f") == 0
|| strcmp(projinfo->key[i], "rf") == 0)
continue;
G_set_key_value(projinfo->key[i], projinfo->value[i],
temp_projinfo);
}
/* Finally add datum and ellipsoid names */
G_set_key_value("datum", dstruct.name, temp_projinfo);
G_message(_("Datum set to <%s>"), dstruct.name);
G_set_key_value("ellps", dstruct.ellps, temp_projinfo);
G_message(_("Ellipsoid set to <%s>"), dstruct.ellps);
/* Destroy original key/value structure and replace with new one */
G_free_key_value(projinfo);
projinfo = temp_projinfo;
return 1;
}
/**
*
* \brief Add or replace datum transformation parameters to the current
* co-ordinate system definition
*
* \param datumtrans Index number of parameter set to use, 0 to leave
* unspecified (or remove specific parameters, leaving just
* the datum name), -1 to list the available parameter
* sets for this datum and exit.
*
* \param force Force editing of parameters even if current co-ordinate
* system already contains fully specified parameters.
*
* \return 1 if a change was made, 0 if not.
**/
int set_datumtrans(int datumtrans, int force)
{
char *params, *datum = NULL;
int paramsets, status;
if (cellhd.proj == PROJECTION_XY)
return 0;
status = GPJ__get_datum_params(projinfo, &datum, ¶ms);
G_debug(3, "set_datumtrans(): GPJ__get_datum_params() status=%d", status);
G_free(params);
if (datum) {
/* A datum name is specified; need to determine if
* there are parameters to choose from for this datum */
struct gpj_datum dstruct;
if (GPJ_get_datum_by_name(datum, &dstruct) > 0) {
char *defparams;
paramsets =
GPJ_get_default_datum_params_by_name(dstruct.name,
&defparams);
G_free(defparams);
GPJ_free_datum(&dstruct);
G_debug(3, "set_datumtrans(): datum transform terms found "
"with %d options", paramsets);
if (paramsets > 1 && (status == 1 || datumtrans != 0))
/* Parameters are missing and there is a choice to be
made / or / user asked to print datum
transformation parameters */
force = 1;
}
else {
/* Datum name not found in table; can't do anything. */
G_debug(3, "set_datumtrans(): Datum name not found in table.");
force = 0;
}
}
else {
/* No datum name; can't do anything. */
G_debug(3, "set_datumtrans(): Datum name either invalid or not supplied.");
force = 0;
}
if (force) {
char *chosenparams = NULL;
char *paramkey, *paramvalue;
struct Key_Value *temp_projinfo;
int i;
/* First of all obtain the new parameters
* through the supplied transform number index */
{
struct gpj_datum_transform_list *list;
if (datumtrans > paramsets)
G_fatal_error
("Invalid transformation number %d; valid range is 1 to %d",
datumtrans, paramsets);
G_debug(3, "set_datumtrans(): looking up available datum "
"transforms for <%s>", datum);
list = GPJ_get_datum_transform_by_name(datum);
if (list != NULL) {
if (datumtrans == -1) {
do {
struct gpj_datum_transform_list *old = list;
fprintf(stdout, "---\n%d\nUsed in %s\n%s\n%s\n",
list->count, list->where_used,
list->params, list->comment);
list = list->next;
GPJ_free_datum_transform(old);
} while (list != NULL);
exit(EXIT_SUCCESS);
}
else {
do {
struct gpj_datum_transform_list *old = list;
if (list->count == datumtrans)
chosenparams = G_store(list->params);
list = list->next;
GPJ_free_datum_transform(old);
} while (list != NULL);
}
}
}
temp_projinfo = G_create_key_value();
/* Copy old PROJ_INFO, skipping out any keys related
* to datum parameters */
for (i = 0; i < projinfo->nitems; i++) {
if (strcmp(projinfo->key[i], "dx") == 0
|| strcmp(projinfo->key[i], "dy") == 0
|| strcmp(projinfo->key[i], "dz") == 0
|| strcmp(projinfo->key[i], "datumparams") == 0
|| strcmp(projinfo->key[i], "nadgrids") == 0
|| strcmp(projinfo->key[i], "towgs84") == 0)
continue;
G_set_key_value(projinfo->key[i], projinfo->value[i],
temp_projinfo);
}
/* Finally add new parameters (if we have them) */
if (chosenparams != NULL) {
/* Now split 'chosenparams' into key/value format */
paramkey = strtok(chosenparams, "=");
paramvalue = chosenparams + strlen(paramkey) + 1;
G_set_key_value(paramkey, paramvalue, temp_projinfo);
G_free(chosenparams);
}
/* Destroy original key/value structure and replace with new one */
G_free_key_value(projinfo);
projinfo = temp_projinfo;
}
G_free(datum);
return force;
}