• Main Page
  • Related Pages
  • Data Structures
  • Files
  • File List
  • Globals

range.c

Go to the documentation of this file.
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 }

Generated on Wed Oct 13 2010 12:09:30 for GRASS Programmer's Manual by  doxygen 1.7.1