/src/proj/src/datum_set.cpp
Line | Count | Source (jump to first uncovered line) |
1 | | /****************************************************************************** |
2 | | * Project: PROJ.4 |
3 | | * Purpose: Apply datum definition to PJ structure from initialization string. |
4 | | * Author: Frank Warmerdam, warmerda@home.com |
5 | | * |
6 | | ****************************************************************************** |
7 | | * Copyright (c) 2000, Frank Warmerdam |
8 | | * |
9 | | * Permission is hereby granted, free of charge, to any person obtaining a |
10 | | * copy of this software and associated documentation files (the "Software"), |
11 | | * to deal in the Software without restriction, including without limitation |
12 | | * the rights to use, copy, modify, merge, publish, distribute, sublicense, |
13 | | * and/or sell copies of the Software, and to permit persons to whom the |
14 | | * Software is furnished to do so, subject to the following conditions: |
15 | | * |
16 | | * The above copyright notice and this permission notice shall be included |
17 | | * in all copies or substantial portions of the Software. |
18 | | * |
19 | | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS |
20 | | * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
21 | | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL |
22 | | * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
23 | | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING |
24 | | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER |
25 | | * DEALINGS IN THE SOFTWARE. |
26 | | *****************************************************************************/ |
27 | | |
28 | | #include <string.h> |
29 | | |
30 | | #include "proj.h" |
31 | | #include "proj_internal.h" |
32 | | |
33 | | /* SEC_TO_RAD = Pi/180/3600 */ |
34 | 15.6k | #define SEC_TO_RAD 4.84813681109535993589914102357e-6 |
35 | | |
36 | | /************************************************************************/ |
37 | | /* pj_datum_set() */ |
38 | | /************************************************************************/ |
39 | | |
40 | | int pj_datum_set(PJ_CONTEXT *ctx, paralist *pl, PJ *projdef) |
41 | | |
42 | 125k | { |
43 | 125k | const char *name, *towgs84, *nadgrids; |
44 | | |
45 | 125k | projdef->datum_type = PJD_UNKNOWN; |
46 | | |
47 | | /* -------------------------------------------------------------------- */ |
48 | | /* Is there a datum definition in the parameters list? If so, */ |
49 | | /* add the defining values to the parameter list. Note that */ |
50 | | /* this will append the ellipse definition as well as the */ |
51 | | /* towgs84= and related parameters. It should also be pointed */ |
52 | | /* out that the addition is permanent rather than temporary */ |
53 | | /* like most other keyword expansion so that the ellipse */ |
54 | | /* definition will last into the pj_ell_set() function called */ |
55 | | /* after this one. */ |
56 | | /* -------------------------------------------------------------------- */ |
57 | 125k | if ((name = pj_param(ctx, pl, "sdatum").s) != nullptr) { |
58 | 7.39k | paralist *curr; |
59 | 7.39k | const char *s; |
60 | 7.39k | int i; |
61 | | |
62 | | /* find the end of the list, so we can add to it */ |
63 | 118k | for (curr = pl; curr && curr->next; curr = curr->next) { |
64 | 111k | } |
65 | | |
66 | | /* cannot happen in practice, but makes static analyzers happy */ |
67 | 7.39k | if (!curr) |
68 | 0 | return -1; |
69 | | |
70 | | /* find the datum definition */ |
71 | 7.39k | const struct PJ_DATUMS *pj_datums = pj_get_datums_ref(); |
72 | 17.2k | for (i = 0; (s = pj_datums[i].id) && strcmp(name, s); ++i) { |
73 | 9.89k | } |
74 | | |
75 | 7.39k | if (!s) { |
76 | 52 | pj_log(ctx, PJ_LOG_ERROR, _("Unknown value for datum")); |
77 | 52 | proj_context_errno_set(ctx, PROJ_ERR_INVALID_OP_ILLEGAL_ARG_VALUE); |
78 | 52 | return 1; |
79 | 52 | } |
80 | | |
81 | 7.34k | if (pj_datums[i].ellipse_id && strlen(pj_datums[i].ellipse_id) > 0) { |
82 | 7.34k | char entry[100]; |
83 | | |
84 | 7.34k | strcpy(entry, "ellps="); |
85 | 7.34k | strncpy(entry + strlen(entry), pj_datums[i].ellipse_id, |
86 | 7.34k | sizeof(entry) - 1 - strlen(entry)); |
87 | 7.34k | entry[sizeof(entry) - 1] = '\0'; |
88 | | |
89 | 7.34k | auto param = pj_mkparam(entry); |
90 | 7.34k | if (nullptr == param) { |
91 | 0 | proj_context_errno_set(ctx, PROJ_ERR_OTHER /*ENOMEM*/); |
92 | 0 | return 1; |
93 | 0 | } |
94 | 7.34k | curr->next = param; |
95 | 7.34k | curr = param; |
96 | 7.34k | } |
97 | | |
98 | 7.34k | if (pj_datums[i].defn && strlen(pj_datums[i].defn) > 0) { |
99 | 7.34k | auto param = pj_mkparam(pj_datums[i].defn); |
100 | 7.34k | if (nullptr == param) { |
101 | 0 | proj_context_errno_set(ctx, PROJ_ERR_OTHER /*ENOMEM*/); |
102 | 0 | return 1; |
103 | 0 | } |
104 | 7.34k | curr->next = param; |
105 | | /* curr = param; */ |
106 | 7.34k | } |
107 | 7.34k | } |
108 | | |
109 | | /* -------------------------------------------------------------------- */ |
110 | | /* Check for nadgrids parameter. */ |
111 | | /* -------------------------------------------------------------------- */ |
112 | 125k | nadgrids = pj_param(ctx, pl, "snadgrids").s; |
113 | 125k | if (nadgrids != nullptr) { |
114 | | /* We don't actually save the value separately. It will continue |
115 | | to exist int he param list for use in pj_apply_gridshift.c */ |
116 | | |
117 | 6.37k | projdef->datum_type = PJD_GRIDSHIFT; |
118 | 6.37k | } |
119 | | |
120 | | /* -------------------------------------------------------------------- */ |
121 | | /* Check for towgs84 parameter. */ |
122 | | /* -------------------------------------------------------------------- */ |
123 | 118k | else if ((towgs84 = pj_param(ctx, pl, "stowgs84").s) != nullptr) { |
124 | 17.5k | int parm_count = 0; |
125 | 17.5k | const char *s; |
126 | | |
127 | 17.5k | memset(projdef->datum_params, 0, sizeof(double) * 7); |
128 | | |
129 | | /* parse out the parameters */ |
130 | 93.6k | for (s = towgs84; *s != '\0' && parm_count < 7;) { |
131 | 76.0k | projdef->datum_params[parm_count++] = pj_atof(s); |
132 | 615k | while (*s != '\0' && *s != ',') |
133 | 539k | s++; |
134 | 76.0k | if (*s == ',') |
135 | 60.3k | s++; |
136 | 76.0k | } |
137 | | |
138 | 17.5k | if (projdef->datum_params[3] != 0.0 || |
139 | 17.5k | projdef->datum_params[4] != 0.0 || |
140 | 17.5k | projdef->datum_params[5] != 0.0 || |
141 | 17.5k | projdef->datum_params[6] != 0.0) { |
142 | 5.20k | projdef->datum_type = PJD_7PARAM; |
143 | | |
144 | | /* transform from arc seconds to radians */ |
145 | 5.20k | projdef->datum_params[3] *= SEC_TO_RAD; |
146 | 5.20k | projdef->datum_params[4] *= SEC_TO_RAD; |
147 | 5.20k | projdef->datum_params[5] *= SEC_TO_RAD; |
148 | | /* transform from parts per million to scaling factor */ |
149 | 5.20k | projdef->datum_params[6] = |
150 | 5.20k | (projdef->datum_params[6] / 1000000.0) + 1; |
151 | 5.20k | } else |
152 | 12.3k | projdef->datum_type = PJD_3PARAM; |
153 | | |
154 | | /* Note that pj_init() will later switch datum_type to |
155 | | PJD_WGS84 if shifts are all zero, and ellipsoid is WGS84 or GRS80 */ |
156 | 17.5k | } |
157 | | |
158 | 125k | return 0; |
159 | 125k | } |