GRASS GIS 7 Programmer's Manual  7.0.2(2015)-r00000
adj_cellhd.c
Go to the documentation of this file.
1 
14 #include <grass/gis.h>
15 #include <grass/glocale.h>
16 
38 void G_adjust_Cell_head(struct Cell_head *cellhd, int row_flag, int col_flag)
39 {
40  if (!row_flag) {
41  if (cellhd->ns_res <= 0)
42  G_fatal_error(_("Illegal n-s resolution value"));
43  }
44  else {
45  if (cellhd->rows <= 0)
46  G_fatal_error(_("Illegal row value"));
47  }
48  if (!col_flag) {
49  if (cellhd->ew_res <= 0)
50  G_fatal_error(_("Illegal e-w resolution value"));
51  }
52  else {
53  if (cellhd->cols <= 0)
54  G_fatal_error(_("Illegal col value"));
55  }
56 
57  /* for lat/lon, check north,south. force east larger than west */
58  if (cellhd->proj == PROJECTION_LL) {
59  double epsilon_ns, epsilon_ew;
60 
61  /* TODO: find good thresholds */
62  epsilon_ns = 1. / cellhd->rows * 0.001;
63  epsilon_ew = .000001; /* epsilon_ew calculation doesn't work due to cellhd->cols update/global wraparound below */
64 
65  G_debug(3, "G_adjust_Cell_head: epsilon_ns: %g, epsilon_ew: %g",
66  epsilon_ns, epsilon_ew);
67 
68  /* TODO: once working, change below G_warning to G_debug */
69 
70  /* fix rounding problems if input map slightly exceeds the world definition -180 90 180 -90 */
71  if (cellhd->north > 90.0) {
72  if (((cellhd->north - 90.0) < epsilon_ns) &&
73  ((cellhd->north - 90.0) > GRASS_EPSILON)) {
74  G_warning(_("Fixing subtle input data rounding error of north boundary (%g>%g)"),
75  cellhd->north - 90.0, epsilon_ns);
76  cellhd->north = 90.0;
77  }
78  else
79  G_fatal_error(_("Illegal latitude for North"));
80  }
81 
82  if (cellhd->south < -90.0) {
83  if (((cellhd->south + 90.0) < epsilon_ns) &&
84  ((cellhd->south + 90.0) < GRASS_EPSILON)) {
85  G_warning(_("Fixing subtle input data rounding error of south boundary (%g>%g)"),
86  cellhd->south + 90.0, epsilon_ns);
87  cellhd->south = -90.0;
88  }
89  else
90  G_fatal_error(_("Illegal latitude for South"));
91  }
92 
93 #if 0
94  /* DISABLED: this breaks global wrap-around */
95 
96  G_debug(3,
97  "G_adjust_Cell_head() cellhd->west: %f, devi: %g, eps: %g",
98  cellhd->west, cellhd->west + 180.0, epsilon_ew);
99 
100  if ((cellhd->west < -180.0) && ((cellhd->west + 180.0) < epsilon_ew)
101  && ((cellhd->west + 180.0) < GRASS_EPSILON)) {
102  G_warning(_("Fixing subtle input data rounding error of west boundary (%g>%g)"),
103  cellhd->west + 180.0, epsilon_ew);
104  cellhd->west = -180.0;
105  }
106 
107  G_debug(3,
108  "G_adjust_Cell_head() cellhd->east: %f, devi: %g, eps: %g",
109  cellhd->east, cellhd->east - 180.0, epsilon_ew);
110 
111  if ((cellhd->east > 180.0) && ((cellhd->east - 180.0) > epsilon_ew)
112  && ((cellhd->east - 180.0) > GRASS_EPSILON)) {
113  G_warning(_("Fixing subtle input data rounding error of east boundary (%g>%g)"),
114  cellhd->east - 180.0, epsilon_ew);
115  cellhd->east = 180.0;
116  }
117 #endif
118 
119  while (cellhd->east <= cellhd->west)
120  cellhd->east += 360.0;
121  }
122 
123  /* check the edge values */
124  if (cellhd->north <= cellhd->south) {
125  if (cellhd->proj == PROJECTION_LL)
126  G_fatal_error(_("North must be north of South"));
127  else
128  G_fatal_error(_("North must be larger than South"));
129  }
130  if (cellhd->east <= cellhd->west)
131  G_fatal_error(_("East must be larger than West"));
132 
133  /* compute rows and columns, if not set */
134  if (!row_flag) {
135  cellhd->rows =
136  (cellhd->north - cellhd->south +
137  cellhd->ns_res / 2.0) / cellhd->ns_res;
138  if (cellhd->rows == 0)
139  cellhd->rows = 1;
140  }
141  if (!col_flag) {
142  cellhd->cols =
143  (cellhd->east - cellhd->west +
144  cellhd->ew_res / 2.0) / cellhd->ew_res;
145  if (cellhd->cols == 0)
146  cellhd->cols = 1;
147  }
148 
149  if (cellhd->cols < 0 || cellhd->rows < 0) {
150  G_fatal_error(_("Invalid coordinates"));
151  }
152 
153 
154  /* (re)compute the resolutions */
155  cellhd->ns_res = (cellhd->north - cellhd->south) / cellhd->rows;
156  cellhd->ew_res = (cellhd->east - cellhd->west) / cellhd->cols;
157 }
158 
186 void G_adjust_Cell_head3(struct Cell_head *cellhd, int row_flag,
187  int col_flag, int depth_flag)
188 {
189  if (!row_flag) {
190  if (cellhd->ns_res <= 0)
191  G_fatal_error(_("Illegal n-s resolution value"));
192  if (cellhd->ns_res3 <= 0)
193  G_fatal_error(_("Illegal n-s3 resolution value"));
194  }
195  else {
196  if (cellhd->rows <= 0)
197  G_fatal_error(_("Illegal row value"));
198  if (cellhd->rows3 <= 0)
199  G_fatal_error(_("Illegal row3 value"));
200  }
201  if (!col_flag) {
202  if (cellhd->ew_res <= 0)
203  G_fatal_error(_("Illegal e-w resolution value"));
204  if (cellhd->ew_res3 <= 0)
205  G_fatal_error(_("Illegal e-w3 resolution value"));
206  }
207  else {
208  if (cellhd->cols <= 0)
209  G_fatal_error(_("Illegal col value"));
210  if (cellhd->cols3 <= 0)
211  G_fatal_error(_("Illegal col3 value"));
212  }
213  if (!depth_flag) {
214  if (cellhd->tb_res <= 0)
215  G_fatal_error(_("Illegal t-b3 resolution value"));
216  }
217  else {
218  if (cellhd->depths <= 0)
219  G_fatal_error(_("Illegal depths value"));
220  }
221 
222  /* for lat/lon, check north,south. force east larger than west */
223  if (cellhd->proj == PROJECTION_LL) {
224  double epsilon_ns, epsilon_ew;
225 
226  /* TODO: find good thresholds */
227  epsilon_ns = 1. / cellhd->rows * 0.001;
228  epsilon_ew = .000001; /* epsilon_ew calculation doesn't work due to cellhd->cols update/global wraparound below */
229 
230  G_debug(3, "G_adjust_Cell_head: epsilon_ns: %g, epsilon_ew: %g",
231  epsilon_ns, epsilon_ew);
232 
233  /* TODO: once working, change below G_warning to G_debug */
234 
235  /* fix rounding problems if input map slightly exceeds the world definition -180 90 180 -90 */
236  if (cellhd->north > 90.0) {
237  if (((cellhd->north - 90.0) < epsilon_ns) &&
238  ((cellhd->north - 90.0) > GRASS_EPSILON)) {
239  G_warning(_("Fixing subtle input data rounding error of north boundary (%g>%g)"),
240  cellhd->north - 90.0, epsilon_ns);
241  cellhd->north = 90.0;
242  }
243  else
244  G_fatal_error(_("Illegal latitude for North"));
245  }
246 
247  if (cellhd->south < -90.0) {
248  if (((cellhd->south + 90.0) < epsilon_ns) &&
249  ((cellhd->south + 90.0) < GRASS_EPSILON)) {
250  G_warning(_("Fixing subtle input data rounding error of south boundary (%g>%g)"),
251  cellhd->south + 90.0, epsilon_ns);
252  cellhd->south = -90.0;
253  }
254  else
255  G_fatal_error(_("Illegal latitude for South"));
256  }
257 
258 #if 0
259  /* DISABLED: this breaks global wrap-around */
260 
261  G_debug(3,
262  "G_adjust_Cell_head3() cellhd->west: %f, devi: %g, eps: %g",
263  cellhd->west, cellhd->west + 180.0, epsilon_ew);
264 
265  if ((cellhd->west < -180.0) && ((cellhd->west + 180.0) < epsilon_ew)
266  && ((cellhd->west + 180.0) < GRASS_EPSILON)) {
267  G_warning(_("Fixing subtle input data rounding error of west boundary (%g>%g)"),
268  cellhd->west + 180.0, epsilon_ew);
269  cellhd->west = -180.0;
270  }
271 
272  G_debug(3,
273  "G_adjust_Cell_head3() cellhd->east: %f, devi: %g, eps: %g",
274  cellhd->east, cellhd->east - 180.0, epsilon_ew);
275 
276  if ((cellhd->east > 180.0) && ((cellhd->east - 180.0) > epsilon_ew)
277  && ((cellhd->east - 180.0) > GRASS_EPSILON)) {
278  G_warning(_("Fixing subtle input data rounding error of east boundary (%g>%g)"),
279  cellhd->east - 180.0, epsilon_ew);
280  cellhd->east = 180.0;
281  }
282 #endif
283 
284  while (cellhd->east <= cellhd->west)
285  cellhd->east += 360.0;
286  }
287 
288  /* check the edge values */
289  if (cellhd->north <= cellhd->south) {
290  if (cellhd->proj == PROJECTION_LL)
291  G_fatal_error(_("North must be north of South"));
292  else
293  G_fatal_error(_("North must be larger than South"));
294  }
295  if (cellhd->east <= cellhd->west)
296  G_fatal_error(_("East must be larger than West"));
297 
298  if (cellhd->top <= cellhd->bottom)
299  G_fatal_error(_("Top must be larger than Bottom"));
300 
301  /* compute rows and columns, if not set */
302  if (!row_flag) {
303  cellhd->rows =
304  (cellhd->north - cellhd->south +
305  cellhd->ns_res / 2.0) / cellhd->ns_res;
306  if (cellhd->rows == 0)
307  cellhd->rows = 1;
308 
309  cellhd->rows3 =
310  (cellhd->north - cellhd->south +
311  cellhd->ns_res3 / 2.0) / cellhd->ns_res3;
312  if (cellhd->rows3 == 0)
313  cellhd->rows3 = 1;
314  }
315  if (!col_flag) {
316  cellhd->cols =
317  (cellhd->east - cellhd->west +
318  cellhd->ew_res / 2.0) / cellhd->ew_res;
319  if (cellhd->cols == 0)
320  cellhd->cols = 1;
321 
322  cellhd->cols3 =
323  (cellhd->east - cellhd->west +
324  cellhd->ew_res3 / 2.0) / cellhd->ew_res3;
325  if (cellhd->cols3 == 0)
326  cellhd->cols3 = 1;
327  }
328 
329  if (!depth_flag) {
330  cellhd->depths =
331  (cellhd->top - cellhd->bottom +
332  cellhd->tb_res / 2.0) / cellhd->tb_res;
333  if (cellhd->depths == 0)
334  cellhd->depths = 1;
335 
336  }
337 
338  if (cellhd->cols < 0 || cellhd->rows < 0 || cellhd->cols3 < 0 ||
339  cellhd->rows3 < 0 || cellhd->depths < 0) {
340  G_fatal_error(_("Invalid coordinates"));
341  }
342 
343  /* (re)compute the resolutions */
344  cellhd->ns_res = (cellhd->north - cellhd->south) / cellhd->rows;
345  cellhd->ns_res3 = (cellhd->north - cellhd->south) / cellhd->rows3;
346  cellhd->ew_res = (cellhd->east - cellhd->west) / cellhd->cols;
347  cellhd->ew_res3 = (cellhd->east - cellhd->west) / cellhd->cols3;
348  cellhd->tb_res = (cellhd->top - cellhd->bottom) / cellhd->depths;
349 }
void G_adjust_Cell_head3(struct Cell_head *cellhd, int row_flag, int col_flag, int depth_flag)
Adjust cell header for 3D values.
Definition: adj_cellhd.c:186
void G_adjust_Cell_head(struct Cell_head *cellhd, int row_flag, int col_flag)
Adjust cell header.
Definition: adj_cellhd.c:38
void G_fatal_error(const char *msg,...)
Print a fatal error message to stderr.
Definition: gis/error.c:159
int G_debug(int level, const char *msg,...)
Print debugging message.
Definition: debug.c:65
void G_warning(const char *msg,...)
Print a warning message to stderr.
Definition: gis/error.c:203