16 #include <grass/gis.h>
17 #include <grass/glocale.h>
19 #define LL_TOLERANCE 10
23 static double llepsilon = 0.01;
24 static double fpepsilon = 1.0e-9;
26 static int ll_wrap(
struct Cell_head *cellhd);
27 static int ll_check_ns(
struct Cell_head *cellhd);
28 static int ll_check_ew(
struct Cell_head *cellhd);
56 if (cellhd->ns_res <= 0)
61 if (cellhd->rows <= 0)
63 " (resolution is %g)"),
64 cellhd->rows, cellhd->ns_res);
67 if (cellhd->ew_res <= 0)
72 if (cellhd->cols <= 0)
74 " (resolution is %g)"),
75 cellhd->cols, cellhd->ew_res);
79 if (cellhd->north <= cellhd->south) {
80 if (cellhd->proj == PROJECTION_LL)
82 " but %g (north) <= %g (south"),
83 cellhd->north, cellhd->south);
86 " but %g (north) <= %g (south"),
87 cellhd->north, cellhd->south);
92 if (cellhd->east <= cellhd->west)
94 " but %g (east) <= %g (west)"),
95 cellhd->east, cellhd->west);
100 (cellhd->north - cellhd->south +
101 cellhd->ns_res / 2.0) / cellhd->ns_res;
102 if (cellhd->rows == 0)
107 (cellhd->east - cellhd->west +
108 cellhd->ew_res / 2.0) / cellhd->ew_res;
109 if (cellhd->cols == 0)
113 if (cellhd->cols < 0) {
114 G_fatal_error(_(
"Invalid coordinates: negative number of columns"));
116 if (cellhd->rows < 0) {
117 G_fatal_error(_(
"Invalid coordinates: negative number of rows"));
121 old_res = cellhd->ns_res;
122 cellhd->ns_res = (cellhd->north - cellhd->south) / cellhd->rows;
123 if (old_res > 0 && fabs(old_res - cellhd->ns_res) / old_res > 0.01)
126 old_res = cellhd->ew_res;
127 cellhd->ew_res = (cellhd->east - cellhd->west) / cellhd->cols;
128 if (old_res > 0 && fabs(old_res - cellhd->ew_res) / old_res > 0.01)
131 if (fabs(cellhd->ns_res - cellhd->ew_res) / cellhd->ns_res > 0.01)
166 int col_flag,
int depth_flag)
171 if (cellhd->ns_res <= 0)
174 if (cellhd->ns_res3 <= 0)
179 if (cellhd->rows <= 0)
181 " (resolution is %g)"),
182 cellhd->rows, cellhd->ns_res);
183 if (cellhd->rows3 <= 0)
185 " (resolution is %g)"),
186 cellhd->rows3, cellhd->ns_res3);
189 if (cellhd->ew_res <= 0)
192 if (cellhd->ew_res3 <= 0)
197 if (cellhd->cols <= 0)
199 " (resolution is %g)"),
200 cellhd->cols, cellhd->ew_res);
201 if (cellhd->cols3 <= 0)
203 " (resolution is %g)"),
204 cellhd->cols3, cellhd->ew_res3);
207 if (cellhd->tb_res <= 0)
212 if (cellhd->depths <= 0)
213 G_fatal_error(_(
"Illegal depths value: %d"), cellhd->depths);
217 if (cellhd->north <= cellhd->south) {
218 if (cellhd->proj == PROJECTION_LL)
220 " but %g (north) <= %g (south"),
221 cellhd->north, cellhd->south);
224 " but %g (north) <= %g (south"),
225 cellhd->north, cellhd->south);
230 if (cellhd->east <= cellhd->west)
232 " but %g (east) <= %g (west)"),
233 cellhd->east, cellhd->west);
235 if (cellhd->top <= cellhd->bottom)
237 " but %g (top) <= %g (bottom)"),
238 cellhd->top, cellhd->bottom);
243 (cellhd->north - cellhd->south +
244 cellhd->ns_res / 2.0) / cellhd->ns_res;
245 if (cellhd->rows == 0)
249 (cellhd->north - cellhd->south +
250 cellhd->ns_res3 / 2.0) / cellhd->ns_res3;
251 if (cellhd->rows3 == 0)
256 (cellhd->east - cellhd->west +
257 cellhd->ew_res / 2.0) / cellhd->ew_res;
258 if (cellhd->cols == 0)
262 (cellhd->east - cellhd->west +
263 cellhd->ew_res3 / 2.0) / cellhd->ew_res3;
264 if (cellhd->cols3 == 0)
270 (cellhd->top - cellhd->bottom +
271 cellhd->tb_res / 2.0) / cellhd->tb_res;
272 if (cellhd->depths == 0)
276 if (cellhd->cols < 0 || cellhd->cols3 < 0) {
277 G_fatal_error(_(
"Invalid coordinates: negative number of columns"));
279 if (cellhd->rows < 0 || cellhd->rows3 < 0) {
280 G_fatal_error(_(
"Invalid coordinates: negative number of rows"));
282 if (cellhd->depths < 0) {
283 G_fatal_error(_(
"Invalid coordinates: negative number of depths"));
287 old_res = cellhd->ns_res;
288 cellhd->ns_res = (cellhd->north - cellhd->south) / cellhd->rows;
289 if (old_res > 0 && fabs(old_res - cellhd->ns_res) / old_res > 0.01)
292 old_res = cellhd->ew_res;
293 cellhd->ew_res = (cellhd->east - cellhd->west) / cellhd->cols;
294 if (old_res > 0 && fabs(old_res - cellhd->ew_res) / old_res > 0.01)
297 if (fabs(cellhd->ns_res - cellhd->ew_res) / cellhd->ns_res > 0.01)
303 cellhd->ns_res3 = (cellhd->north - cellhd->south) / cellhd->rows3;
304 cellhd->ew_res3 = (cellhd->east - cellhd->west) / cellhd->cols3;
305 cellhd->tb_res = (cellhd->top - cellhd->bottom) / cellhd->depths;
308 static int ll_wrap(
struct Cell_head *cellhd)
313 if (cellhd->proj != PROJECTION_LL)
316 if (cellhd->east <= cellhd->west) {
317 G_warning(_(
"East (%.15g) is not larger than West (%.15g)"),
318 cellhd->east, cellhd->west);
320 while (cellhd->east <= cellhd->west)
321 cellhd->east += 360.0;
330 while (cellhd->west + shift >= 180) {
333 while (cellhd->east + shift <= -180) {
338 while (cellhd->east + shift > 360) {
341 while (cellhd->west + shift <= -360) {
346 cellhd->west += shift;
347 cellhd->east += shift;
352 G_fatal_error(_(
"Illegal latitude for North: %g"), cellhd->north);
354 G_fatal_error(_(
"Illegal latitude for South: %g"), cellhd->south);
359 G_debug(1,
"East: %g", cellhd->east);
360 G_fatal_error(_(
"Illegal longitude for West: %g"), cellhd->west);
363 G_debug(1,
"West: %g", cellhd->west);
364 G_fatal_error(_(
"Illegal longitude for East: %g"), cellhd->east);
371 static int ll_check_ns(
struct Cell_head *cellhd)
378 if (cellhd->proj != PROJECTION_LL)
383 G_debug(3,
"ll_check_ns: epsilon: %g", llepsilon);
387 diff = (cellhd->north - cellhd->south) / cellhd->ns_res;
388 ncells = (
int) (diff + 0.5);
390 if ((diff < 0 && diff < -fpepsilon) ||
391 (diff > 0 && diff > fpepsilon)) {
392 G_verbose_message(_(
"NS extent does not match NS resolution: %g cells difference"),
397 diff = (cellhd->north - 90) / cellhd->ns_res;
400 if (cellhd->north < 90.0 && diff < 1.0 ) {
403 if (diff < llepsilon && diff > fpepsilon) {
405 cellhd->north - 90.0);
412 if (cellhd->north > 90.0) {
413 if (diff <= 0.5 + llepsilon) {
417 if (diff < llepsilon && diff > fpepsilon) {
419 cellhd->north - 90.0);
420 G_debug(1,
"North of north in seconds: %g",
421 (cellhd->north - 90.0) * 3600);
431 if (diff < llepsilon && diff > fpepsilon) {
433 cellhd->north - 90.0 - cellhd->ns_res / 2.0);
434 G_debug(1,
"North of north + 0.5 cells in seconds: %g",
435 (cellhd->north - 90.0 - cellhd->ns_res / 2.0) * 3600);
447 diff = (cellhd->south + 90) / cellhd->ns_res;
450 if (cellhd->south > -90.0 && diff < 1.0 ) {
453 if (diff < llepsilon && diff > fpepsilon) {
455 cellhd->south + 90.0);
462 if (cellhd->south < -90.0) {
463 if (diff <= 0.5 + llepsilon) {
467 if (diff < llepsilon && diff > fpepsilon) {
470 G_debug(1,
"South of south in seconds: %g",
471 (-cellhd->south - 90) * 3600);
481 if (diff < llepsilon && diff > fpepsilon) {
483 cellhd->south + 90 + cellhd->ns_res / 2.0);
484 G_debug(1,
"South of south + 0.5 cells in seconds: %g",
485 (-cellhd->south - 90 - cellhd->ns_res / 2.0) * 3600);
497 cellhd->ns_res = (cellhd->north - cellhd->south) / cellhd->rows;
502 static int ll_check_ew(
struct Cell_head *cellhd)
509 if (cellhd->proj != PROJECTION_LL)
514 G_debug(3,
"ll_check_ew: epsilon: %g", llepsilon);
517 diff = (cellhd->east - cellhd->west) / cellhd->ew_res;
518 ncells = (
int) (diff + 0.5);
520 if ((diff < 0 && diff < -fpepsilon) ||
521 (diff > 0 && diff > fpepsilon)) {
522 G_verbose_message(_(
"EW extent does not match EW resolution: %g cells difference"),
525 if (cellhd->east - cellhd->west > 360.0) {
526 diff = (cellhd->east - cellhd->west - 360.0) / cellhd->ew_res;
527 if (diff > fpepsilon)
531 else if (cellhd->east - cellhd->west < 360.0) {
532 diff = (360.0 - (cellhd->east - cellhd->west)) / cellhd->ew_res;
533 if (diff < 1.0 && diff > fpepsilon)
555 int ll_adjust, res_adj;
557 char buf[100], buf2[100];
560 struct Cell_head cellhds;
563 if (cellhd->proj != PROJECTION_LL)
570 cellhd->ns_res =
new;
575 cellhd->ew_res =
new;
600 old = cellhds.ns_res * 3600;
601 sprintf(buf,
"%f", old);
602 sscanf(buf,
"%lf", &
new);
603 cellhds.ns_res =
new;
605 old = cellhds.ew_res * 3600;
606 sprintf(buf,
"%f", old);
607 sscanf(buf,
"%lf", &
new);
608 cellhds.ew_res =
new;
610 old = cellhds.north * 3600;
611 sprintf(buf,
"%f", old);
612 sscanf(buf,
"%lf", &
new);
615 old = cellhds.south * 3600;
616 sprintf(buf,
"%f", old);
617 sscanf(buf,
"%lf", &
new);
620 old = cellhds.west * 3600;
621 sprintf(buf,
"%f", old);
622 sscanf(buf,
"%lf", &
new);
625 old = cellhds.east * 3600;
626 sprintf(buf,
"%f", old);
627 sscanf(buf,
"%lf", &
new);
635 old = cellhds.ns_res;
640 dsec2 = floor(dsec + 0.5);
642 diff = fabs(dsec2 - dsec) / dsec;
643 if (diff > 0 && diff < llepsilon) {
646 if (strcmp(buf, buf2))
651 cellhds.ns_res =
new;
660 dsec2 = floor(dsec + 0.5);
661 diff = fabs(dsec2 - dsec) / (cellhds.ns_res * 10);
666 dsec2 = floor(dsec + 0.5);
667 diff = fabs(dsec2 - dsec) / (cellhds.ns_res * 10);
670 if (n_off < llepsilon || n_off <= s_off) {
673 dsec2 = floor(dsec + 0.5);
676 if (diff > 0 && diff < llepsilon) {
679 if (strcmp(buf, buf2))
686 new = cellhds.north - cellhds.ns_res * cellhds.rows;
687 diff = fabs(
new - old) / cellhds.ns_res;
691 if (strcmp(buf, buf2))
700 dsec2 = floor(dsec + 0.5);
703 if (diff > 0 && diff < llepsilon) {
706 if (strcmp(buf, buf2))
713 new = cellhds.south + cellhds.ns_res * cellhds.rows;
714 diff = fabs(
new - old) / cellhds.ns_res;
718 if (strcmp(buf, buf2))
728 dsec2 = floor(dsec + 0.5);
730 diff = fabs(dsec2 - dsec) / (cellhds.ns_res * 10);
731 if (diff > 0 && diff < llepsilon) {
734 if (strcmp(buf, buf2))
743 dsec2 = floor(dsec + 0.5);
745 diff = fabs(dsec2 - dsec) / (cellhds.ns_res * 10);
746 if (diff > 0 && diff < llepsilon) {
749 if (strcmp(buf, buf2))
756 cellhds.ns_res = (cellhds.north - cellhds.south) / cellhds.rows;
761 old = cellhds.ew_res;
766 dsec2 = floor(dsec + 0.5);
768 diff = fabs(dsec2 - dsec) / dsec;
769 if (diff > 0 && diff < llepsilon) {
772 if (strcmp(buf, buf2))
777 cellhds.ew_res =
new;
786 dsec2 = floor(dsec + 0.5);
787 diff = fabs(dsec2 - dsec) / (cellhds.ew_res * 10);
792 dsec2 = floor(dsec + 0.5);
793 diff = fabs(dsec2 - dsec) / (cellhds.ew_res * 10);
796 if (w_off < llepsilon || w_off <= e_off) {
799 dsec2 = floor(dsec + 0.5);
802 if (diff > 0 && diff < llepsilon) {
805 if (strcmp(buf, buf2))
812 new = cellhds.west + cellhds.ew_res * cellhds.cols;
813 diff = fabs(
new - old) / cellhds.ew_res;
817 if (strcmp(buf, buf2))
826 dsec2 = floor(dsec + 0.5);
829 if (diff > 0 && diff < llepsilon) {
832 if (strcmp(buf, buf2))
839 new = cellhds.east - cellhds.ew_res * cellhds.cols;
840 diff = fabs(
new - cellhds.west) / cellhds.ew_res;
844 if (strcmp(buf, buf2))
854 dsec2 = floor(dsec + 0.5);
856 diff = fabs(dsec2 - dsec) / (cellhds.ew_res * 10);
857 if (diff > 0 && diff < llepsilon) {
860 if (strcmp(buf, buf2))
869 dsec2 = floor(dsec + 0.5);
871 diff = fabs(dsec2 - dsec) / (cellhds.ew_res * 10);
872 if (diff > 0 && diff < llepsilon) {
875 if (strcmp(buf, buf2))
882 cellhds.ew_res = (cellhds.east - cellhds.west) / cellhds.cols;
884 cellhd->ns_res = cellhds.ns_res / 3600;
885 cellhd->ew_res = cellhds.ew_res / 3600;
886 cellhd->north = cellhds.north / 3600;
887 cellhd->south = cellhds.south / 3600;
888 cellhd->west = cellhds.west / 3600;
889 cellhd->east = cellhds.east / 3600;
void G_adjust_Cell_head3(struct Cell_head *cellhd, int row_flag, int col_flag, int depth_flag)
Adjust cell header for 3D values.
void G_adjust_Cell_head(struct Cell_head *cellhd, int row_flag, int col_flag)
Adjust cell header.
int G_adjust_window_ll(struct Cell_head *cellhd)
Adjust window for lat/lon.
if(!DBFLoadRecord(psDBF, hEntity)) return NULL
int G_debug(int level, const char *msg,...)
Print debugging message.
void G_verbose_message(const char *msg,...)
Print a message to stderr but only if module is in verbose mode.
void G_important_message(const char *msg,...)
Print a message to stderr even in brief mode (verbosity=1)
void G_fatal_error(const char *msg,...)
Print a fatal error message to stderr.
void G_warning(const char *msg,...)
Print a warning message to stderr.
int G_lat_scan(const char *buf, double *lat)
int G_lon_scan(const char *buf, double *lon)
int G_llres_scan(const char *buf, double *res)