17#include <grass/glocale.h>
19#define LL_TOLERANCE 10
23static double llepsilon = 0.01;
24static double fpepsilon = 1.0e-9;
26static int ll_wrap(
struct Cell_head *cellhd);
27static int ll_check_ns(
struct Cell_head *cellhd);
28static 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;
308static 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);
371static 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);
443 G_fatal_error(_(
"Illegal latitude for North: %g"), cellhd->north);
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);
493 G_fatal_error(_(
"Illegal latitude for South: %g"), cellhd->south);
497 cellhd->ns_res = (cellhd->north - cellhd->south) / cellhd->rows;
502static 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)
529 " (East: %g, West: %g)"),
530 diff, cellhd->east, cellhd->west);
532 else if (cellhd->east - cellhd->west < 360.0) {
533 diff = (360.0 - (cellhd->east - cellhd->west)) / cellhd->ew_res;
534 if (diff < 1.0 && diff > fpepsilon)
556 int ll_adjust, res_adj;
558 char buf[100], buf2[100];
561 struct Cell_head cellhds;
564 if (cellhd->proj != PROJECTION_LL)
571 cellhd->ns_res =
new;
576 cellhd->ew_res =
new;
601 old = cellhds.ns_res * 3600;
602 sprintf(buf,
"%f", old);
603 sscanf(buf,
"%lf", &
new);
604 cellhds.ns_res =
new;
606 old = cellhds.ew_res * 3600;
607 sprintf(buf,
"%f", old);
608 sscanf(buf,
"%lf", &
new);
609 cellhds.ew_res =
new;
611 old = cellhds.north * 3600;
612 sprintf(buf,
"%f", old);
613 sscanf(buf,
"%lf", &
new);
616 old = cellhds.south * 3600;
617 sprintf(buf,
"%f", old);
618 sscanf(buf,
"%lf", &
new);
621 old = cellhds.west * 3600;
622 sprintf(buf,
"%f", old);
623 sscanf(buf,
"%lf", &
new);
626 old = cellhds.east * 3600;
627 sprintf(buf,
"%f", old);
628 sscanf(buf,
"%lf", &
new);
636 old = cellhds.ns_res;
641 dsec2 = floor(dsec + 0.5);
643 diff = fabs(dsec2 - dsec) / dsec;
644 if (diff > 0 && diff < llepsilon) {
647 if (strcmp(buf, buf2))
652 cellhds.ns_res =
new;
661 dsec2 = floor(dsec + 0.5);
662 diff = fabs(dsec2 - dsec) / (cellhds.ns_res * 10);
667 dsec2 = floor(dsec + 0.5);
668 diff = fabs(dsec2 - dsec) / (cellhds.ns_res * 10);
671 if (n_off < llepsilon || n_off <= s_off) {
674 dsec2 = floor(dsec + 0.5);
677 if (diff > 0 && diff < llepsilon) {
680 if (strcmp(buf, buf2))
687 new = cellhds.north - cellhds.ns_res * cellhds.rows;
688 diff = fabs(
new - old) / cellhds.ns_res;
692 if (strcmp(buf, buf2))
701 dsec2 = floor(dsec + 0.5);
704 if (diff > 0 && diff < llepsilon) {
707 if (strcmp(buf, buf2))
714 new = cellhds.south + cellhds.ns_res * cellhds.rows;
715 diff = fabs(
new - old) / cellhds.ns_res;
719 if (strcmp(buf, buf2))
729 dsec2 = floor(dsec + 0.5);
731 diff = fabs(dsec2 - dsec) / (cellhds.ns_res * 10);
732 if (diff > 0 && diff < llepsilon) {
735 if (strcmp(buf, buf2))
744 dsec2 = floor(dsec + 0.5);
746 diff = fabs(dsec2 - dsec) / (cellhds.ns_res * 10);
747 if (diff > 0 && diff < llepsilon) {
750 if (strcmp(buf, buf2))
757 cellhds.ns_res = (cellhds.north - cellhds.south) / cellhds.rows;
762 old = cellhds.ew_res;
767 dsec2 = floor(dsec + 0.5);
769 diff = fabs(dsec2 - dsec) / dsec;
770 if (diff > 0 && diff < llepsilon) {
773 if (strcmp(buf, buf2))
778 cellhds.ew_res =
new;
787 dsec2 = floor(dsec + 0.5);
788 diff = fabs(dsec2 - dsec) / (cellhds.ew_res * 10);
793 dsec2 = floor(dsec + 0.5);
794 diff = fabs(dsec2 - dsec) / (cellhds.ew_res * 10);
797 if (w_off < llepsilon || w_off <= e_off) {
800 dsec2 = floor(dsec + 0.5);
803 if (diff > 0 && diff < llepsilon) {
806 if (strcmp(buf, buf2))
813 new = cellhds.west + cellhds.ew_res * cellhds.cols;
814 diff = fabs(
new - old) / cellhds.ew_res;
818 if (strcmp(buf, buf2))
827 dsec2 = floor(dsec + 0.5);
830 if (diff > 0 && diff < llepsilon) {
833 if (strcmp(buf, buf2))
840 new = cellhds.east - cellhds.ew_res * cellhds.cols;
841 diff = fabs(
new - cellhds.west) / cellhds.ew_res;
845 if (strcmp(buf, buf2))
855 dsec2 = floor(dsec + 0.5);
857 diff = fabs(dsec2 - dsec) / (cellhds.ew_res * 10);
858 if (diff > 0 && diff < llepsilon) {
861 if (strcmp(buf, buf2))
870 dsec2 = floor(dsec + 0.5);
872 diff = fabs(dsec2 - dsec) / (cellhds.ew_res * 10);
873 if (diff > 0 && diff < llepsilon) {
876 if (strcmp(buf, buf2))
883 cellhds.ew_res = (cellhds.east - cellhds.west) / cellhds.cols;
885 cellhd->ns_res = cellhds.ns_res / 3600;
886 cellhd->ew_res = cellhds.ew_res / 3600;
887 cellhd->north = cellhds.north / 3600;
888 cellhd->south = cellhds.south / 3600;
889 cellhd->west = cellhds.west / 3600;
890 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)