00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080 #include <unistd.h>
00081 #include <rpc/types.h>
00082 #include <rpc/xdr.h>
00083 #include "G.h"
00084 #include <grass/glocale.h>
00085 #define DEFAULT_CELL_MIN 1
00086 #define DEFAULT_CELL_MAX 255
00087
00088
00089
00090
00091
00092
00093
00094
00095 int G__remove_fp_range(const char *name)
00096 {
00097 G_remove_misc("cell_misc", "f_range", name);
00098
00099 return 0;
00100 }
00101
00102
00112 int G_construct_default_range(struct Range *range)
00113 {
00114 G_update_range(DEFAULT_CELL_MIN, range);
00115 G_update_range(DEFAULT_CELL_MAX, range);
00116
00117 return 0;
00118 }
00119
00120
00139 int G_read_fp_range(const char *name, const char *mapset,
00140 struct FPRange *drange)
00141 {
00142 struct Range range;
00143 int fd;
00144 char buf[200], xdr_buf[100];
00145 DCELL dcell1, dcell2;
00146 XDR xdr_str;
00147
00148 G_init_fp_range(drange);
00149
00150 if (G_raster_map_type(name, mapset) == CELL_TYPE) {
00151
00152
00153
00154 if (G_read_range(name, mapset, &range) >= 0) {
00155
00156 if (range.first_time)
00157 return 2;
00158
00159 G_update_fp_range((DCELL) range.min, drange);
00160 G_update_fp_range((DCELL) range.max, drange);
00161 return 1;
00162 }
00163 return -1;
00164 }
00165
00166 fd = -1;
00167
00168 if (G_find_file2_misc("cell_misc", "f_range", name, mapset)) {
00169 fd = G_open_old_misc("cell_misc", "f_range", name, mapset);
00170 if (fd < 0)
00171 goto error;
00172
00173 if (read(fd, xdr_buf, 2 * XDR_DOUBLE_NBYTES) != 2 * XDR_DOUBLE_NBYTES)
00174 return 2;
00175
00176 xdrmem_create(&xdr_str, xdr_buf, (u_int) XDR_DOUBLE_NBYTES * 2,
00177 XDR_DECODE);
00178
00179
00180 if (!xdr_double(&xdr_str, &dcell1) || !xdr_double(&xdr_str, &dcell2))
00181 goto error;
00182
00183 G_update_fp_range(dcell1, drange);
00184 G_update_fp_range(dcell2, drange);
00185 close(fd);
00186 return 1;
00187 }
00188
00189 error:
00190 if (fd > 0)
00191 close(fd);
00192 sprintf(buf, _("can't read f_range file for [%s in %s]"), name, mapset);
00193 G_warning(buf);
00194 return -1;
00195 }
00196
00197
00198
00199
00226 int G_read_range(const char *name, const char *mapset, struct Range *range)
00227 {
00228 FILE *fd;
00229 CELL x[4];
00230 char buf[200];
00231 int n, count;
00232 struct Quant quant;
00233 struct FPRange drange;
00234
00235 G_init_range(range);
00236 fd = NULL;
00237
00238
00239 if (G_raster_map_type(name, mapset) != CELL_TYPE) {
00240 DCELL dmin, dmax;
00241
00242 if (G_read_quant(name, mapset, &quant) < 0) {
00243 sprintf(buf,
00244 "G_read_range(): can't read quant rules for fp map %s@%s",
00245 name, mapset);
00246 G_warning(buf);
00247 return -1;
00248 }
00249 if (G_quant_is_truncate(&quant) || G_quant_is_round(&quant)) {
00250 if (G_read_fp_range(name, mapset, &drange) >= 0) {
00251 G_get_fp_range_min_max(&drange, &dmin, &dmax);
00252 if (G_quant_is_truncate(&quant)) {
00253 x[0] = (CELL) dmin;
00254 x[1] = (CELL) dmax;
00255 }
00256 else {
00257
00258 if (dmin > 0)
00259 x[0] = (CELL) (dmin + .5);
00260 else
00261 x[0] = (CELL) (dmin - .5);
00262 if (dmax > 0)
00263 x[1] = (CELL) (dmax + .5);
00264 else
00265 x[1] = (CELL) (dmax - .5);
00266 }
00267 }
00268 else
00269 return -1;
00270 }
00271 else
00272 G_quant_get_limits(&quant, &dmin, &dmax, &x[0], &x[1]);
00273
00274 G_update_range(x[0], range);
00275 G_update_range(x[1], range);
00276 return 3;
00277 }
00278
00279 if (G_find_file2_misc("cell_misc", "range", name, mapset)) {
00280 fd = G_fopen_old_misc("cell_misc", "range", name, mapset);
00281 if (!fd)
00282 goto error;
00283
00284
00285 if (!fgets(buf, sizeof buf, fd))
00286 return 2;
00287
00288 x[0] = x[1] = x[2] = x[3] = 0;
00289 count = sscanf(buf, "%d%d%d%d", &x[0], &x[1], &x[2], &x[3]);
00290
00291
00292 if (count <= 0)
00293 goto error;
00294
00295 for (n = 0; n < count; n++) {
00296
00297
00298 if (count < 4 || x[n])
00299 G_update_range((CELL) x[n], range);
00300 }
00301 fclose(fd);
00302 return 1;
00303 }
00304
00305 error:
00306 if (fd)
00307 fclose(fd);
00308 sprintf(buf, _("can't read range file for [%s in %s]"), name, mapset);
00309 G_warning(buf);
00310 return -1;
00311 }
00312
00313
00314
00315
00334 int G_write_range(const char *name, const struct Range *range)
00335 {
00336 FILE *fd;
00337 char buf[200];
00338
00339 if (G_raster_map_type(name, G_mapset()) != CELL_TYPE) {
00340 sprintf(buf, "G_write_range(): the map is floating point!");
00341 goto error;
00342 }
00343 fd = G_fopen_new_misc("cell_misc", "range", name);
00344 if (!fd)
00345 goto error;
00346
00347 if (range->first_time)
00348
00349 {
00350 fclose(fd);
00351 return 0;
00352 }
00353 fprintf(fd, "%ld %ld\n", (long)range->min, (long)range->max);
00354 fclose(fd);
00355 return 0;
00356
00357 error:
00358 G_remove_misc("cell_misc", "range", name);
00359 sprintf(buf, _("can't write range file for [%s in %s]"),
00360 name, G_mapset());
00361 G_warning(buf);
00362 return -1;
00363 }
00364
00365
00366
00367
00380 int G_write_fp_range(const char *name, const struct FPRange *range)
00381 {
00382 int fd;
00383 char buf[200], xdr_buf[100];
00384 XDR xdr_str;
00385
00386 sprintf(buf, "cell_misc/%s", name);
00387 fd = G_open_new(buf, "f_range");
00388 if (fd < 0)
00389 goto error;
00390
00391 if (range->first_time)
00392
00393 {
00394 close(fd);
00395 return 0;
00396 }
00397
00398 xdrmem_create(&xdr_str, xdr_buf, (u_int) XDR_DOUBLE_NBYTES * 2,
00399 XDR_ENCODE);
00400
00401 if (!xdr_double(&xdr_str, (double *)&(range->min)))
00402 goto error;
00403 if (!xdr_double(&xdr_str, (double *)&(range->max)))
00404 goto error;
00405
00406 write(fd, xdr_buf, XDR_DOUBLE_NBYTES * 2);
00407 close(fd);
00408 return 0;
00409
00410 error:
00411 G_remove(buf, "f_range");
00412 sprintf(buf, _("can't write range file for [%s in %s]"),
00413 name, G_mapset());
00414 G_warning(buf);
00415 return -1;
00416 }
00417
00418
00419
00420
00436 int G_update_range(CELL cat, struct Range *range)
00437 {
00438 if (!G_is_c_null_value(&cat)) {
00439 if (range->first_time) {
00440 range->first_time = 0;
00441 range->min = cat;
00442 range->max = cat;
00443 return 0;
00444 }
00445 if (cat < range->min)
00446 range->min = cat;
00447 if (cat > range->max)
00448 range->max = cat;
00449 }
00450
00451 return 0;
00452 }
00453
00454
00455
00456 int G_update_fp_range(DCELL val, struct FPRange *range)
00457 {
00458 if (!G_is_d_null_value(&val)) {
00459 if (range->first_time) {
00460 range->first_time = 0;
00461 range->min = val;
00462 range->max = val;
00463 return 0;
00464 }
00465 if (val < range->min)
00466 range->min = val;
00467 if (val > range->max)
00468 range->max = val;
00469 }
00470 return 0;
00471 }
00472
00473
00474
00475
00489 int G_row_update_range(const CELL * cell, int n, struct Range *range)
00490 {
00491 G__row_update_range(cell, n, range, 0);
00492
00493 return 0;
00494 }
00495
00496
00497
00498 int G__row_update_range(const CELL * cell, int n,
00499 struct Range *range, int ignore_zeros)
00500 {
00501 CELL cat;
00502
00503 while (n-- > 0) {
00504 cat = *cell++;
00505 if (G_is_c_null_value(&cat) || (ignore_zeros && !cat))
00506 continue;
00507 if (range->first_time) {
00508 range->first_time = 0;
00509 range->min = cat;
00510 range->max = cat;
00511 continue;
00512 }
00513 if (cat < range->min)
00514 range->min = cat;
00515 if (cat > range->max)
00516 range->max = cat;
00517 }
00518
00519 return 0;
00520 }
00521
00522
00523
00524 int G_row_update_fp_range(const void *rast, int n,
00525 struct FPRange *range, RASTER_MAP_TYPE data_type)
00526 {
00527 DCELL val = 0L;
00528
00529 while (n-- > 0) {
00530 switch (data_type) {
00531 case CELL_TYPE:
00532 val = (DCELL) * ((CELL *) rast);
00533 break;
00534 case FCELL_TYPE:
00535 val = (DCELL) * ((FCELL *) rast);
00536 break;
00537 case DCELL_TYPE:
00538 val = *((DCELL *) rast);
00539 break;
00540 }
00541
00542 if (G_is_null_value(rast, data_type)) {
00543 rast = G_incr_void_ptr(rast, G_raster_size(data_type));
00544 continue;
00545 }
00546 if (range->first_time) {
00547 range->first_time = 0;
00548 range->min = val;
00549 range->max = val;
00550 }
00551 else {
00552 if (val < range->min)
00553 range->min = val;
00554 if (val > range->max)
00555 range->max = val;
00556 }
00557
00558 rast = G_incr_void_ptr(rast, G_raster_size(data_type));
00559 }
00560
00561 return 0;
00562 }
00563
00564
00565
00579 int G_init_range(struct Range *range)
00580 {
00581 G_set_c_null_value(&(range->min), 1);
00582 G_set_c_null_value(&(range->max), 1);
00583 range->first_time = 1;
00584
00585 return 0;
00586 }
00587
00588
00589
00590
00608 int G_get_range_min_max(const struct Range *range, CELL * min, CELL * max)
00609 {
00610 if (range->first_time) {
00611 G_set_c_null_value(min, 1);
00612 G_set_c_null_value(max, 1);
00613 }
00614 else {
00615 if (G_is_c_null_value(&(range->min)))
00616 G_set_c_null_value(min, 1);
00617 else
00618 *min = range->min;
00619
00620 if (G_is_c_null_value(&(range->max)))
00621 G_set_c_null_value(max, 1);
00622 else
00623 *max = range->max;
00624 }
00625
00626 return 0;
00627 }
00628
00629
00630
00642 int G_init_fp_range(struct FPRange *range)
00643 {
00644 G_set_d_null_value(&(range->min), 1);
00645 G_set_d_null_value(&(range->max), 1);
00646 range->first_time = 1;
00647
00648 return 0;
00649 }
00650
00651
00652
00653
00667 int G_get_fp_range_min_max(const struct FPRange *range,
00668 DCELL * min, DCELL * max)
00669 {
00670 if (range->first_time) {
00671 G_set_d_null_value(min, 1);
00672 G_set_d_null_value(max, 1);
00673 }
00674 else {
00675 if (G_is_d_null_value(&(range->min)))
00676 G_set_d_null_value(min, 1);
00677 else
00678 *min = range->min;
00679
00680 if (G_is_d_null_value(&(range->max)))
00681 G_set_d_null_value(max, 1);
00682 else
00683 *max = range->max;
00684 }
00685
00686 return 0;
00687 }