1 /*
2 * projection checking
3 *
4 * Copyright 2011-2015 by Markus Metz, and The GRASS Development Team
5 * Authors:
6 * Markus Metz (v.in.lidar)
7 * Vaclav Petras (move code to standalone functions)
8 *
9 * This program is free software licensed under the GPL (>=v2).
10 * Read the COPYING file that comes with GRASS for details.
11 *
12 */
13
14 #include <string.h>
15
16 #include <grass/gis.h>
17 #include <grass/glocale.h>
18 #include <grass/gprojects.h>
19
projection_mismatch_report(struct Cell_head cellhd,struct Cell_head loc_wind,struct Key_Value * loc_proj_info,struct Key_Value * loc_proj_units,struct Key_Value * proj_info,struct Key_Value * proj_units,int err)20 void projection_mismatch_report(struct Cell_head cellhd,
21 struct Cell_head loc_wind,
22 struct Key_Value *loc_proj_info,
23 struct Key_Value *loc_proj_units,
24 struct Key_Value *proj_info,
25 struct Key_Value *proj_units, int err)
26 {
27 int i_value;
28 char error_msg[8192];
29
30 strcpy(error_msg,
31 _("Projection of dataset does not"
32 " appear to match current location.\n\n"));
33
34 /* TODO: output this info sorted by key: */
35 if (loc_wind.proj != cellhd.proj || err != -2) {
36 if (loc_proj_info != NULL) {
37 strcat(error_msg, _("GRASS LOCATION PROJ_INFO is:\n"));
38 for (i_value = 0; i_value < loc_proj_info->nitems; i_value++)
39 sprintf(error_msg + strlen(error_msg), "%s: %s\n",
40 loc_proj_info->key[i_value],
41 loc_proj_info->value[i_value]);
42 strcat(error_msg, "\n");
43 }
44
45 if (proj_info != NULL) {
46 strcat(error_msg, _("Import dataset PROJ_INFO is:\n"));
47 for (i_value = 0; i_value < proj_info->nitems; i_value++)
48 sprintf(error_msg + strlen(error_msg), "%s: %s\n",
49 proj_info->key[i_value], proj_info->value[i_value]);
50 }
51 else {
52 strcat(error_msg, _("Import dataset PROJ_INFO is:\n"));
53 if (cellhd.proj == PROJECTION_XY)
54 sprintf(error_msg + strlen(error_msg),
55 "Dataset proj = %d (unreferenced/unknown)\n",
56 cellhd.proj);
57 else if (cellhd.proj == PROJECTION_LL)
58 sprintf(error_msg + strlen(error_msg),
59 "Dataset proj = %d (lat/long)\n", cellhd.proj);
60 else if (cellhd.proj == PROJECTION_UTM)
61 sprintf(error_msg + strlen(error_msg),
62 "Dataset proj = %d (UTM), zone = %d\n",
63 cellhd.proj, cellhd.zone);
64 else
65 sprintf(error_msg + strlen(error_msg),
66 "Dataset proj = %d (unknown), zone = %d\n",
67 cellhd.proj, cellhd.zone);
68 }
69 }
70 else {
71 if (loc_proj_units != NULL) {
72 strcat(error_msg, "GRASS LOCATION PROJ_UNITS is:\n");
73 for (i_value = 0; i_value < loc_proj_units->nitems; i_value++)
74 sprintf(error_msg + strlen(error_msg), "%s: %s\n",
75 loc_proj_units->key[i_value],
76 loc_proj_units->value[i_value]);
77 strcat(error_msg, "\n");
78 }
79
80 if (proj_units != NULL) {
81 strcat(error_msg, "Import dataset PROJ_UNITS is:\n");
82 for (i_value = 0; i_value < proj_units->nitems; i_value++)
83 sprintf(error_msg + strlen(error_msg), "%s: %s\n",
84 proj_units->key[i_value], proj_units->value[i_value]);
85 }
86 }
87 sprintf(error_msg + strlen(error_msg),
88 _("\nIn case of no significant differences in the projection definitions,"
89 " use the -o flag to ignore them and use"
90 " current location definition.\n"));
91 strcat(error_msg,
92 _("Consider generating a new location with 'location' parameter"
93 " from input data set.\n"));
94 G_fatal_error("%s", error_msg);
95 }
96
projection_check_wkt(struct Cell_head cellhd,struct Cell_head loc_wind,const char * projstr,int override,int verbose)97 void projection_check_wkt(struct Cell_head cellhd,
98 struct Cell_head loc_wind,
99 const char *projstr, int override, int verbose)
100 {
101 struct Key_Value *loc_proj_info = NULL, *loc_proj_units = NULL;
102 struct Key_Value *proj_info, *proj_units;
103 int err = 0;
104
105 proj_info = NULL;
106 proj_units = NULL;
107
108 /* Projection only required for checking so convert non-interactively */
109 if (GPJ_wkt_to_grass(&cellhd, &proj_info, &proj_units, projstr, 0) < 0)
110 G_warning(_("Unable to convert input map projection information to "
111 "GRASS format for checking"));
112
113 /* Does the projection of the current location match the dataset? */
114
115 /* fetch LOCATION PROJ info */
116 if (loc_wind.proj != PROJECTION_XY) {
117 loc_proj_info = G_get_projinfo();
118 loc_proj_units = G_get_projunits();
119 }
120
121 if (override) {
122 cellhd.proj = loc_wind.proj;
123 cellhd.zone = loc_wind.zone;
124 if (verbose)
125 G_message(_("Overriding projection check"));
126 }
127 else if (loc_wind.proj != cellhd.proj
128 || (err =
129 G_compare_projections(loc_proj_info, loc_proj_units,
130 proj_info, proj_units)) != TRUE) {
131 projection_mismatch_report(cellhd, loc_wind, loc_proj_info,
132 loc_proj_units,
133 proj_info, proj_units, err);
134 }
135 else {
136 if (verbose) {
137 G_message(_("Projection of input dataset and current location "
138 "appear to match"));
139 }
140 }
141 }
142
143
144 /* Does the projection of the current location match the dataset? */
is_wkt_projection_same_as_loc(const char * wkt)145 int is_wkt_projection_same_as_loc(const char *wkt)
146 {
147 struct Key_Value *loc_proj_info = NULL, *loc_proj_units = NULL;
148 struct Key_Value *proj_info = NULL, *proj_units = NULL;
149 struct Cell_head cellhd;
150 struct Cell_head loc_wind;
151
152 G_get_default_window(&loc_wind);
153
154 /* Projection only required for checking so convert non-interactively */
155 if (GPJ_wkt_to_grass(&cellhd, &proj_info, &proj_units, wkt, 0) < 0)
156 G_warning(_("Unable to convert input map projection information to "
157 "GRASS format for checking"));
158
159 /* fetch LOCATION PROJ info */
160 if (loc_wind.proj != PROJECTION_XY) {
161 loc_proj_info = G_get_projinfo();
162 loc_proj_units = G_get_projunits();
163 }
164
165 if (loc_wind.proj != cellhd.proj) {
166 return FALSE;
167 }
168 else if (G_compare_projections(loc_proj_info, loc_proj_units,
169 proj_info, proj_units) != 1) {
170 return FALSE;
171 }
172 else {
173 return TRUE;
174 }
175 }
176
177 /* Does the projection of the current location match the dataset? */
wkt_projection_mismatch_report(const char * wkt)178 void wkt_projection_mismatch_report(const char *wkt)
179 {
180 struct Key_Value *loc_proj_info = NULL, *loc_proj_units = NULL;
181 struct Key_Value *proj_info = NULL, *proj_units = NULL;
182 struct Cell_head cellhd;
183 struct Cell_head loc_wind;
184
185 G_get_default_window(&loc_wind);
186
187 /* Projection only required for checking so convert non-interactively */
188 if (GPJ_wkt_to_grass(&cellhd, &proj_info, &proj_units, wkt, 0) < 0)
189 G_warning(_("Unable to convert input map projection information to "
190 "GRASS format for checking"));
191
192 /* fetch LOCATION PROJ info */
193 if (loc_wind.proj != PROJECTION_XY) {
194 loc_proj_info = G_get_projinfo();
195 loc_proj_units = G_get_projunits();
196 }
197 int err = G_compare_projections(loc_proj_info, loc_proj_units,
198 proj_info, proj_units);
199
200 projection_mismatch_report(cellhd, loc_wind, loc_proj_info,
201 loc_proj_units, proj_info, proj_units, err);
202 }
203
204 /* caller should free the returned string */
location_projection_as_wkt(int prettify)205 char *location_projection_as_wkt(int prettify)
206 {
207 struct Key_Value *proj_info = G_get_projinfo();
208 struct Key_Value *proj_units = G_get_projunits();
209 char *proj_wkt = GPJ_grass_to_wkt(proj_info, proj_units, FALSE, prettify);
210
211 G_free_key_value(proj_info);
212 G_free_key_value(proj_units);
213 return proj_wkt;
214 }
215