GRASS Programmer's Manual 6.4.1(2011)
|
00001 00002 /********************************************************************** 00003 * 00004 * G_read_range (name, mapset, range) 00005 * const char *name name of map 00006 * const char *mapset mapset that map belongs to 00007 * struct Range *range struct to hold range info 00008 * 00009 * Reads the data range information associated with map layer "map" 00010 * in mapset "mapset" 00011 * 00012 * returns: 1 if successful 00013 * 2 range is empty 00014 * 3 map is fp: get range from quant rules 00015 * -1 on fail 00016 * 00017 * note: a warning message is printed if the file is missing or incorrect 00018 * 00019 ********************************************************************** 00020 * 00021 * G_read_fp_range (name, mapset, range) 00022 * const char *name name of map 00023 * const char *mapset mapset that map belongs to 00024 * struct FPRange *range struct to hold range info 00025 * 00026 * Reads the fp data range information associated with map layer "map" 00027 * in mapset "mapset" . If map is integer, the integer range is read 00028 * and the max and min values are casted to doubles and copied to FPRange 00029 * 00030 * returns: 1 if successful 00031 * 2 range is empty 00032 * -1 on fail 00033 * 00034 * note: a warning message is printed if the file is missing or incorrect 00035 * 00036 ********************************************************************** 00037 * 00038 * G_write_[fp_]range (name, range) 00039 * const char *name name of map 00040 * struct [FP]Range *range struct holding range info 00041 * 00042 * Writes the range information associated with map layer "map" 00043 * 00044 * returns: 0 if successful 00045 * -1 on fail (or if the map is fp ) 00046 * 00047 ********************************************************************** 00048 * 00049 * G_init_[fp_]range (range) 00050 * struct [FP]Range *range struct for range info 00051 * 00052 * initializes range structure for call to G_update_[fp_]range() 00053 * 00054 ********************************************************************** 00055 * 00056 * G_construct_default_range (range) 00057 * struct Range *range struct for range info 00058 * 00059 * returns 1 and range is set to DEFAULT_CELL_MIN 00060 * and DEFAULT_SET_MAX, otherwise returns -1 00061 * 00062 ********************************************************************** 00063 * 00064 * G_update_[fp_]range (cat, range) 00065 * DCELL cat cat to be factored into range 00066 * struct [FP]Range *range struct for range info 00067 ********************************************************************** 00068 * 00069 * G_row_update_[fp_]range (rast, range, data_type) 00070 * void *rast raster row to be factored into range 00071 * struct [FP]Range *range struct for range info 00072 * RASTER_MAP_TYPE data_type; 00073 ********************************************************************** 00074 * 00075 * G_get_[fp_]range_min_max (range, min, max) 00076 * struct [FP]Range *range; 00077 * [D]CELL *min, *max; 00078 **********************************************************************/ 00079 00080 #include <unistd.h> 00081 #include <rpc/types.h> /* need this for sgi */ 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 /* range functions for type "Range" */ 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 /* if map is integer 00152 read integer range and convert it to double */ 00153 00154 if (G_read_range(name, mapset, &range) >= 0) { 00155 /* if the integer range is empty */ 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 /* if the f_range file exists, but empty */ 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 /* if map is not integer, read quant rules, and get limits */ 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 { /* round */ 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 /* if range file exists but empty */ 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 /* if wrong format */ 00292 if (count <= 0) 00293 goto error; 00294 00295 for (n = 0; n < count; n++) { 00296 /* if count==4, the range file is old (4.1) and 0's in it 00297 have to be ignored */ 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 /* if range hasn't been updated */ 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); /* remove the old file with this 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 /* if range hasn't been updated, write empty file meaning Nulls */ 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"); /* remove the old file with this name */ 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 }