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 #include <unistd.h>
00080 #include <rpc/types.h>
00081 #include <rpc/xdr.h>
00082 #include "G.h"
00083 #include <grass/glocale.h>
00084 #define DEFAULT_CELL_MIN 1
00085 #define DEFAULT_CELL_MAX 255
00086
00087
00088
00089
00090
00091
00092
00093 int G__remove_fp_range ( char *name)
00094 {
00095 char buf[200];
00096
00097 sprintf (buf,"cell_misc/%s", name);
00098 G_remove(buf, "f_range");
00099
00100 return 0;
00101 }
00102
00103
00113 int G_construct_default_range ( struct Range *range)
00114 {
00115 G_update_range (DEFAULT_CELL_MIN, range);
00116 G_update_range (DEFAULT_CELL_MAX, range);
00117
00118 return 0;
00119 }
00120
00121
00140 int G_read_fp_range (
00141 char *name,char *mapset,
00142 struct FPRange *drange)
00143 {
00144 struct Range range;
00145 int fd;
00146 char buf[200], xdr_buf[100];
00147 DCELL dcell1, dcell2;
00148 XDR xdr_str;
00149
00150 G_init_fp_range(drange);
00151
00152 if (G_raster_map_type (name, mapset) == CELL_TYPE)
00153 {
00154
00155
00156
00157 if(G_read_range (name, mapset, &range) >= 0)
00158 {
00159
00160 if(range.first_time)
00161 return 2;
00162
00163 G_update_fp_range ((DCELL) range.min, drange);
00164 G_update_fp_range ((DCELL) range.max, drange);
00165 return 1;
00166 }
00167 return -1;
00168 }
00169
00170 fd = -1;
00171
00172 sprintf (buf,"cell_misc/%s", name);
00173 if (G_find_file2 (buf, "f_range", mapset))
00174 {
00175 fd = G_open_old(buf, "f_range", mapset);
00176 if (fd< 0 )
00177 goto error;
00178
00179 if(read(fd, xdr_buf, 2 * XDR_DOUBLE_NBYTES) != 2 * XDR_DOUBLE_NBYTES )
00180 return 2;
00181
00182 xdrmem_create (&xdr_str, xdr_buf, (u_int) XDR_DOUBLE_NBYTES * 2,
00183 XDR_DECODE);
00184
00185
00186 if (! xdr_double (&xdr_str, &dcell1) ||
00187 ! xdr_double (&xdr_str, &dcell2))
00188 goto error;
00189
00190 G_update_fp_range (dcell1, drange);
00191 G_update_fp_range (dcell2, drange);
00192 close(fd) ;
00193 return 1;
00194 }
00195
00196 error:
00197 if (fd > 0)
00198 close(fd) ;
00199 sprintf (buf, _("can't read f_range file for [%s in %s]"), name, mapset);
00200 G_warning (buf);
00201 return -1;
00202 }
00203
00204
00205
00206
00233 int G_read_range (
00234 char *name,char *mapset,
00235 struct Range *range)
00236 {
00237 FILE *fd;
00238 CELL x[4];
00239 char buf[200];
00240 int n, count;
00241 struct Quant quant;
00242 struct FPRange drange;
00243
00244 G_init_range(range);
00245 fd = NULL;
00246
00247
00248 if (G_raster_map_type (name, mapset) != CELL_TYPE)
00249 {
00250 DCELL dmin, dmax;
00251 if(G_read_quant(name, mapset, &quant)<0)
00252 {
00253 sprintf(buf, "G_read_range(): can't read quant rules for fp map %s@%s", name, mapset);
00254 G_warning(buf);
00255 return -1;
00256 }
00257 if(G_quant_is_truncate(&quant) || G_quant_is_round(&quant))
00258 {
00259 if(G_read_fp_range(name, mapset, &drange)>=0)
00260 {
00261 G_get_fp_range_min_max(&drange, &dmin, &dmax);
00262 if(G_quant_is_truncate(&quant))
00263 {
00264 x[0] = (CELL) dmin;
00265 x[1] = (CELL) dmax;
00266 }
00267 else
00268 {
00269 if(dmin>0) x[0] = (CELL) (dmin + .5);
00270 else x[0] = (CELL) (dmin - .5);
00271 if(dmax>0) x[1] = (CELL) (dmax + .5);
00272 else x[1] = (CELL) (dmax - .5);
00273 }
00274 }
00275 else return -1;
00276 }
00277 else
00278 G_quant_get_limits (&quant, &dmin, &dmax, &x[0], &x[1]);
00279
00280 G_update_range (x[0], range);
00281 G_update_range (x[1], range);
00282 return 3;
00283 }
00284
00285 sprintf (buf,"cell_misc/%s", name);
00286 if (G_find_file2 (buf, "range", mapset))
00287 {
00288 fd = G_fopen_old (buf, "range", mapset);
00289 if (!fd)
00290 goto error;
00291
00292
00293 if (!fgets (buf, sizeof buf, fd))
00294 return 2;
00295
00296 x[0]=x[1]=x[2]=x[3]=0;
00297 count = sscanf (buf, "%d%d%d%d", &x[0], &x[1], &x[2], &x[3]);
00298
00299
00300 if (count <= 0)
00301 goto error;
00302
00303 for (n = 0 ; n < count ; n++)
00304 {
00305
00306
00307 if(count < 4 || x[n])
00308 G_update_range ((CELL)x[n], range);
00309 }
00310 fclose(fd) ;
00311 return 1;
00312 }
00313
00314 error:
00315 if (fd)
00316 fclose(fd) ;
00317 sprintf (buf, _("can't read range file for [%s in %s]"), name, mapset);
00318 G_warning (buf);
00319 return -1;
00320 }
00321
00322
00323
00324
00343 int G_write_range ( char *name, struct Range *range)
00344 {
00345 FILE *fd;
00346 char buf[200];
00347
00348 if (G_raster_map_type (name, G_mapset()) != CELL_TYPE)
00349 {
00350 sprintf(buf, "G_write_range(): the map is floating point!");
00351 goto error;
00352 }
00353 sprintf (buf,"cell_misc/%s", name);
00354 fd = G_fopen_new (buf, "range");
00355 if (!fd)
00356 goto error;
00357
00358 if(range->first_time)
00359
00360 {
00361 fclose (fd);
00362 return 0;
00363 }
00364 fprintf (fd, "%ld %ld\n",
00365 (long)range->min, (long)range->max);
00366 fclose (fd);
00367 return 0;
00368
00369 error:
00370 G_remove(buf, "range");
00371 sprintf (buf, _("can't write range file for [%s in %s]"),
00372 name, G_mapset());
00373 G_warning (buf);
00374 return -1;
00375 }
00376
00377
00378
00379
00392 int G_write_fp_range ( char *name, struct FPRange *range)
00393 {
00394 int fd;
00395 char buf[200], xdr_buf[100];
00396 XDR xdr_str;
00397
00398 sprintf (buf,"cell_misc/%s", name);
00399 fd = G_open_new (buf, "f_range");
00400 if (fd< 0)
00401 goto error;
00402
00403 if(range->first_time)
00404
00405 {
00406 close (fd);
00407 return 0;
00408 }
00409
00410 xdrmem_create (&xdr_str, xdr_buf, (u_int) XDR_DOUBLE_NBYTES * 2,
00411 XDR_ENCODE);
00412
00413 if (! xdr_double (&xdr_str, &(range->min))) goto error;
00414 if (! xdr_double (&xdr_str, &(range->max))) goto error;
00415
00416 write (fd, xdr_buf, XDR_DOUBLE_NBYTES * 2);
00417 close (fd);
00418 return 0;
00419
00420 error:
00421 G_remove(buf, "f_range");
00422 sprintf (buf, _("can't write range file for [%s in %s]"),
00423 name, G_mapset());
00424 G_warning (buf);
00425 return -1;
00426 }
00427
00428
00429
00430
00446 int G_update_range ( CELL cat, struct Range *range)
00447 {
00448 if (!G_is_c_null_value(&cat))
00449 {
00450 if (range->first_time)
00451 {
00452 range->first_time = 0;
00453 range->min = cat;
00454 range->max = cat;
00455 return 0;
00456 }
00457 if (cat < range->min)
00458 range->min = cat;
00459 if (cat > range->max)
00460 range->max = cat;
00461 }
00462
00463 return 0;
00464 }
00465
00466
00467
00468 int G_update_fp_range ( DCELL val, struct FPRange *range)
00469 {
00470 if (!G_is_d_null_value(&val))
00471 {
00472 if (range->first_time)
00473 {
00474 range->first_time = 0;
00475 range->min = val;
00476 range->max = val;
00477 return 0;
00478 }
00479 if (val < range->min)
00480 range->min = val;
00481 if (val > range->max)
00482 range->max = val;
00483 }
00484 return 0;
00485 }
00486
00487
00488
00489
00503 int G_row_update_range ( CELL *cell,int n, struct Range *range)
00504 {
00505 G__row_update_range (cell, n, range, 0);
00506
00507 return 0;
00508 }
00509
00510
00511
00512 int G__row_update_range (
00513 CELL *cell,int n,
00514 struct Range *range,
00515 int ignore_zeros)
00516 {
00517 CELL cat;
00518
00519 while (n-- > 0)
00520 {
00521 cat = *cell++;
00522 if (G_is_c_null_value(&cat) || (ignore_zeros && !cat))
00523 continue;
00524 if (range->first_time)
00525 {
00526 range->first_time = 0;
00527 range->min = cat;
00528 range->max = cat;
00529 continue;
00530 }
00531 if (cat < range->min)
00532 range->min = cat;
00533 if (cat > range->max)
00534 range->max = cat;
00535 }
00536
00537 return 0;
00538 }
00539
00540
00541
00542 int G_row_update_fp_range (
00543 void *rast,int n,
00544 struct FPRange *range,
00545 RASTER_MAP_TYPE data_type)
00546 {
00547 DCELL val = 0L;
00548
00549 while (n-- > 0)
00550 {
00551 switch(data_type)
00552 {
00553 case CELL_TYPE: val = (DCELL) *((CELL *) rast); break;
00554 case FCELL_TYPE: val = (DCELL) *((FCELL *) rast); break;
00555 case DCELL_TYPE: val = *((DCELL *) rast); break;
00556 }
00557
00558 if (G_is_null_value(rast, data_type))
00559 {
00560 rast = G_incr_void_ptr(rast, G_raster_size(data_type));
00561 continue;
00562 }
00563 if (range->first_time)
00564 {
00565 range->first_time = 0;
00566 range->min = val;
00567 range->max = val;
00568 }
00569 else
00570 {
00571 if (val < range->min)
00572 range->min = val;
00573 if (val > range->max)
00574 range->max = val;
00575 }
00576
00577 rast = G_incr_void_ptr(rast, G_raster_size(data_type));
00578 }
00579
00580 return 0;
00581 }
00582
00583
00584
00598 int G_init_range (struct Range *range)
00599 {
00600 G_set_c_null_value(&(range->min),1);
00601 G_set_c_null_value(&(range->max),1);
00602 range->first_time = 1;
00603
00604 return 0;
00605 }
00606
00607
00608
00609
00627 int G_get_range_min_max(
00628 struct Range *range,
00629 CELL *min,CELL *max)
00630 {
00631 if(range->first_time)
00632 {
00633 G_set_c_null_value(min,1);
00634 G_set_c_null_value(max,1);
00635 }
00636 else
00637 {
00638 if(G_is_c_null_value(&(range->min)))
00639 G_set_c_null_value(min,1);
00640 else
00641 *min = range->min;
00642
00643 if(G_is_c_null_value(&(range->max)))
00644 G_set_c_null_value(max,1);
00645 else
00646 *max = range->max;
00647 }
00648
00649 return 0;
00650 }
00651
00652
00653
00665 int G_init_fp_range ( struct FPRange *range)
00666 {
00667 G_set_d_null_value(&(range->min),1);
00668 G_set_d_null_value(&(range->max),1);
00669 range->first_time = 1;
00670
00671 return 0;
00672 }
00673
00674
00675
00676
00690 int G_get_fp_range_min_max(
00691 struct FPRange *range,
00692 DCELL *min,DCELL *max)
00693 {
00694 if(range->first_time)
00695 {
00696 G_set_d_null_value(min,1);
00697 G_set_d_null_value(max,1);
00698 }
00699 else
00700 {
00701 if(G_is_d_null_value(&(range->min)))
00702 G_set_d_null_value(min,1);
00703 else
00704 *min = range->min;
00705
00706 if(G_is_d_null_value(&(range->max)))
00707 G_set_d_null_value(max,1);
00708 else
00709 *max = range->max;
00710 }
00711
00712 return 0;
00713 }
00714