range.c

Go to the documentation of this file.
00001 /**********************************************************************
00002  *
00003  *  G_read_range (name, mapset, range)
00004  *      char *name                   name of map
00005  *      char *mapset                 mapset that map belongs to
00006  *      struct Range *range          struct to hold range info
00007  *
00008  *  Reads the data range information associated with map layer "map"
00009  *  in mapset "mapset" 
00010  *
00011  *   returns:    1  if successful
00012  *               2  range is empty
00013  *               3  map is fp: get range from quant rules
00014  *              -1  on fail
00015  *
00016  *  note:   a warning message is printed if the file is missing or incorrect
00017  *
00018  **********************************************************************
00019  *
00020  *  G_read_fp_range (name, mapset, range)
00021  *      char *name                   name of map
00022  *      char *mapset                 mapset that map belongs to
00023  *      struct FPRange *range          struct to hold range info
00024  *
00025  *  Reads the fp data range information associated with map layer "map"
00026  *  in mapset "mapset" . If map is integer, the integer range is read
00027  *  and the max and min values are casted to doubles and copied to FPRange
00028  *
00029  *   returns:    1  if successful
00030  *               2  range is empty
00031  *              -1  on fail
00032  *
00033  *  note:   a warning message is printed if the file is missing or incorrect
00034  *
00035  **********************************************************************
00036  *
00037  *  G_write_[fp_]range (name, range)
00038  *      char *name                  name of map
00039  *      struct [FP]Range *range         struct holding range info
00040  *
00041  *  Writes the range information associated with map layer "map"
00042  *
00043  *   returns:    0  if successful
00044  *              -1  on fail (or if the map is fp )
00045  *
00046  **********************************************************************
00047  *
00048  * G_init_[fp_]range (range)
00049  *      struct [FP]Range *range         struct for range info
00050  *
00051  * initializes range structure for call to G_update_[fp_]range()
00052  *
00053  **********************************************************************
00054  *
00055  * G_construct_default_range (range)
00056  *      struct Range *range         struct for range info
00057  *
00058  *  returns 1 and range is set to DEFAULT_CELL_MIN
00059  *  and DEFAULT_SET_MAX, otherwise returns -1
00060  *
00061  **********************************************************************
00062  *
00063  * G_update_[fp_]range (cat, range)
00064  *    DCELL cat                    cat to be factored into range
00065  *    struct [FP]Range *range      struct for range info
00066  **********************************************************************
00067  *
00068  * G_row_update_[fp_]range (rast, range, data_type)
00069  *    void *rast                   raster row to be factored into range
00070  *    struct [FP]Range *range      struct for range info
00071  *    RASTER_MAP_TYPE data_type;
00072  **********************************************************************
00073  *
00074  * G_get_[fp_]range_min_max (range, min, max)
00075  *    struct [FP]Range *range;
00076  *    [D]CELL *min, *max;
00077  **********************************************************************/
00078 
00079 #include <unistd.h>
00080 #include <rpc/types.h> /* need this for sgi */
00081 #include <rpc/xdr.h>
00082 #include "G.h"
00083 #include "glocale.h"
00084 #define DEFAULT_CELL_MIN 1
00085 #define DEFAULT_CELL_MAX 255
00086 
00087 /*-------------------------------------------------------------------------*/
00088 /*-------------------------------------------------------------------------*/
00089 
00090 /* range functions for type "Range" */
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        /* if map is integer
00155            read integer range and convert it to double */
00156 
00157        if(G_read_range (name, mapset, &range) >= 0)
00158        {
00159              /* if the integer range is empty */
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 (fd >= MAXFILES)
00180         {
00181            close (fd);
00182            G_warning(_("Too many open files"));
00183            return -1;
00184         }
00185 
00186         if(read(fd, xdr_buf, 2 * XDR_DOUBLE_NBYTES) != 2 * XDR_DOUBLE_NBYTES )
00187            return 2;
00188 
00189         xdrmem_create (&xdr_str, xdr_buf, (u_int) XDR_DOUBLE_NBYTES * 2,
00190                        XDR_DECODE);
00191         
00192         /* if the f_range file exists, but empty */
00193         if (! xdr_double (&xdr_str, &dcell1) ||
00194             ! xdr_double (&xdr_str, &dcell2)) 
00195             goto error;
00196 
00197         G_update_fp_range (dcell1, drange);
00198         G_update_fp_range (dcell2, drange);
00199         close(fd) ;
00200         return 1;
00201     }
00202 
00203 error:
00204     if (fd > 0)
00205         close(fd) ;
00206     sprintf (buf, _("can't read f_range file for [%s in %s]"), name, mapset);
00207     G_warning (buf);
00208     return -1;
00209 }
00210 
00211 /*-------------------------------------------------------------------------*/
00212 
00213 
00246 int G_read_range (
00247     char *name,char *mapset,
00248     struct Range *range)
00249 {
00250     FILE *fd;
00251     CELL x[4];
00252     char buf[200];
00253     int n, count;
00254     struct Quant quant;
00255     struct FPRange drange;
00256 
00257     G_init_range(range);
00258     fd = NULL;
00259 
00260     /* if map is not integer, read quant rules, and get limits */
00261     if (G_raster_map_type (name, mapset) != CELL_TYPE)
00262     {
00263        DCELL dmin, dmax;
00264        if(G_read_quant(name, mapset, &quant)<0)
00265        {
00266            sprintf(buf, "G_read_range(): can't read quant rules for fp map %s@%s", name, mapset);
00267            G_warning(buf);
00268            return -1;
00269        }
00270        if(G_quant_is_truncate(&quant) || G_quant_is_round(&quant))
00271        {
00272            if(G_read_fp_range(name, mapset, &drange)>=0)
00273            {
00274                G_get_fp_range_min_max(&drange, &dmin, &dmax);
00275                if(G_quant_is_truncate(&quant))
00276                {
00277                    x[0] = (CELL) dmin;
00278                    x[1] = (CELL) dmax;
00279                }
00280                else /* round */
00281                {
00282                    if(dmin>0) x[0] = (CELL) (dmin + .5);
00283                    else x[0] = (CELL) (dmin - .5);
00284                    if(dmax>0) x[1] = (CELL) (dmax + .5);
00285                    else x[1] = (CELL) (dmax - .5);
00286                }
00287             }
00288             else return -1;
00289        }      
00290        else
00291            G_quant_get_limits (&quant, &dmin, &dmax, &x[0], &x[1]);
00292 
00293        G_update_range (x[0], range);
00294        G_update_range (x[1], range);
00295        return 3;
00296     }
00297          
00298     sprintf (buf,"cell_misc/%s", name);
00299     if (G_find_file2 (buf, "range", mapset))
00300     {
00301         fd = G_fopen_old (buf, "range", mapset);
00302         if (!fd)
00303             goto error;
00304 
00305         /* if range file exists but empty */
00306         if (!fgets (buf, sizeof buf, fd))
00307            return 2;
00308 
00309         x[0]=x[1]=x[2]=x[3]=0;
00310         count = sscanf (buf, "%d%d%d%d", &x[0], &x[1], &x[2], &x[3]);
00311 
00312         /* if wrong format */
00313         if (count <= 0)
00314             goto error;
00315 
00316         for (n = 0 ; n < count ; n++)
00317         {
00318            /* if count==4, the range file is old (4.1) and 0's in it
00319               have to be ignored */
00320            if(count < 4 || x[n])
00321               G_update_range ((CELL)x[n], range);
00322         }
00323         fclose(fd) ;
00324         return 1;
00325     }
00326 
00327 error:
00328     if (fd)
00329         fclose(fd) ;
00330     sprintf (buf, _("can't read range file for [%s in %s]"), name, mapset);
00331     G_warning (buf);
00332     return -1;
00333 }
00334 
00335 /*-------------------------------------------------------------------------*/
00336 
00337 
00362 int G_write_range ( char *name, struct Range *range)
00363 {
00364     FILE *fd;
00365     char buf[200];
00366 
00367     if (G_raster_map_type (name, G_mapset()) != CELL_TYPE)
00368     {
00369        sprintf(buf, "G_write_range(): the map is floating point!");
00370        goto error;
00371     }
00372     sprintf (buf,"cell_misc/%s", name);
00373     fd = G_fopen_new (buf, "range");
00374     if (!fd)
00375         goto error;
00376 
00377     if(range->first_time)
00378     /* if range hasn't been updated */
00379     {
00380        fclose (fd);
00381        return 0;
00382     }
00383     fprintf (fd, "%ld %ld\n",
00384         (long)range->min, (long)range->max);
00385     fclose (fd);
00386     return 0;
00387 
00388 error:
00389     G_remove(buf, "range"); /* remove the old file with this name */
00390     sprintf (buf, _("can't write range file for [%s in %s]"),
00391         name, G_mapset());
00392     G_warning (buf);
00393     return -1;
00394 }
00395 
00396 /*-------------------------------------------------------------------------*/
00397 
00398 
00411 int G_write_fp_range ( char *name, struct FPRange *range)
00412 {
00413     int fd;
00414     char buf[200], xdr_buf[100];
00415     XDR xdr_str;
00416 
00417     sprintf (buf,"cell_misc/%s", name);
00418     fd = G_open_new (buf, "f_range");
00419     if (fd< 0)
00420         goto error;
00421 
00422     if(range->first_time)
00423     /* if range hasn't been updated, write empty file meaning Nulls */
00424     {
00425        close (fd);
00426        return 0;
00427     }
00428 
00429     xdrmem_create (&xdr_str, xdr_buf, (u_int) XDR_DOUBLE_NBYTES * 2,
00430                    XDR_ENCODE);
00431 
00432     if (! xdr_double (&xdr_str, &(range->min))) goto error;
00433     if (! xdr_double (&xdr_str, &(range->max))) goto error;
00434 
00435     write (fd, xdr_buf, XDR_DOUBLE_NBYTES * 2);
00436     close (fd);
00437     return 0;
00438 
00439 error:
00440     G_remove(buf, "f_range"); /* remove the old file with this name */
00441     sprintf (buf, _("can't write range file for [%s in %s]"),
00442         name, G_mapset());
00443     G_warning (buf);
00444     return -1;
00445 }
00446 
00447 /*-------------------------------------------------------------------------*/
00448 
00449 
00471 int G_update_range ( CELL cat, struct Range *range)
00472 {
00473     if (!G_is_c_null_value(&cat))
00474     {
00475         if (range->first_time)
00476         {
00477            range->first_time = 0;
00478            range->min = cat;
00479            range->max = cat;
00480            return 0;
00481         }
00482         if (cat < range->min)
00483             range->min = cat;
00484         if (cat > range->max)
00485             range->max = cat;
00486     }
00487 
00488     return 0;
00489 }
00490 
00491 /*-------------------------------------------------------------------------*/
00492 
00493 int G_update_fp_range ( DCELL val, struct FPRange *range)
00494 {
00495     if (!G_is_d_null_value(&val))
00496     {
00497         if (range->first_time)
00498         {
00499            range->first_time = 0;
00500            range->min = val;
00501            range->max = val;
00502            return 0;
00503         }
00504         if (val < range->min)
00505             range->min = val;
00506         if (val > range->max)
00507             range->max = val;
00508     }
00509     return 0;
00510 }
00511 
00512 /*-------------------------------------------------------------------------*/
00513 
00514 
00528 int G_row_update_range ( CELL *cell,int n, struct Range *range)
00529 {
00530     G__row_update_range (cell, n, range, 0);
00531 
00532     return 0;
00533 }
00534 
00535 /*-------------------------------------------------------------------------*/
00536 
00537 int G__row_update_range (
00538     CELL *cell,int n,
00539     struct Range *range,
00540     int ignore_zeros)
00541 {
00542     CELL cat;
00543 
00544     while (n-- > 0)
00545     {
00546         cat = *cell++;
00547         if (G_is_c_null_value(&cat) || (ignore_zeros && !cat))
00548            continue;
00549         if (range->first_time)
00550         {
00551            range->first_time = 0;
00552            range->min = cat;
00553            range->max = cat;
00554            continue;
00555         }
00556         if (cat < range->min)
00557             range->min = cat;
00558         if (cat > range->max)
00559             range->max = cat;
00560     }
00561 
00562     return 0;
00563 }
00564 
00565 /*-------------------------------------------------------------------------*/
00566 
00567 int G_row_update_fp_range (
00568     void *rast,int n,
00569     struct FPRange *range,
00570     RASTER_MAP_TYPE data_type)
00571 {
00572     DCELL val = 0L;
00573 
00574     while (n-- > 0)
00575     {
00576         switch(data_type)
00577         {
00578            case CELL_TYPE: val = (DCELL) *((CELL *) rast); break;
00579            case FCELL_TYPE: val = (DCELL) *((FCELL *) rast); break;
00580            case DCELL_TYPE: val = *((DCELL *) rast); break;
00581         }
00582 
00583         if (G_is_null_value(rast, data_type))
00584         {
00585            rast = G_incr_void_ptr(rast, G_raster_size(data_type));
00586            continue;
00587         }
00588         if (range->first_time)
00589         {
00590            range->first_time = 0;
00591            range->min = val;
00592            range->max = val;
00593            continue;
00594         }
00595         if (val < range->min)
00596             range->min = val;
00597         if (val > range->max)
00598             range->max = val;
00599 
00600         rast = G_incr_void_ptr(rast, G_raster_size(data_type));
00601     }
00602 
00603     return 0;
00604 }
00605 
00606 /*-------------------------------------------------------------------------*/
00607 
00628 int G_init_range (struct Range *range)
00629 {
00630     G_set_c_null_value(&(range->min),1);
00631     G_set_c_null_value(&(range->max),1);
00632     range->first_time = 1;
00633 
00634     return 0;
00635 }
00636 
00637 /*-------------------------------------------------------------------------*/
00638 
00639 
00663 int G_get_range_min_max(
00664     struct Range *range,
00665     CELL *min,CELL *max)
00666 {
00667     if(range->first_time)
00668     {
00669        G_set_c_null_value(min,1);
00670        G_set_c_null_value(max,1);
00671     }
00672     else
00673     {
00674        if(G_is_c_null_value(&(range->min)))
00675            G_set_c_null_value(min,1);
00676        else
00677            *min = range->min;
00678 
00679        if(G_is_c_null_value(&(range->max)))
00680            G_set_c_null_value(max,1);
00681        else
00682            *max = range->max;
00683     }
00684 
00685     return 0;
00686 }
00687 
00688 /*-------------------------------------------------------------------------*/
00689 
00701 int G_init_fp_range ( struct FPRange *range)
00702 {
00703    G_set_d_null_value(&(range->min),1);
00704    G_set_d_null_value(&(range->max),1);
00705    range->first_time = 1;
00706 
00707     return 0;
00708 }
00709 
00710 /*-------------------------------------------------------------------------*/
00711 
00712 
00726 int G_get_fp_range_min_max(
00727     struct FPRange *range,
00728     DCELL *min,DCELL *max)
00729 {
00730     if(range->first_time)
00731     {
00732        G_set_d_null_value(min,1);
00733        G_set_d_null_value(max,1);
00734     }
00735     else
00736     {
00737        if(G_is_d_null_value(&(range->min)))
00738            G_set_d_null_value(min,1);
00739        else
00740            *min = range->min;
00741 
00742        if(G_is_d_null_value(&(range->max)))
00743            G_set_d_null_value(max,1);
00744        else
00745            *max = range->max;
00746     }
00747 
00748     return 0;
00749 }
00750 
00751 /*-------------------------------------------------------------------------*/
00752 /*-------------------------------------------------------------------------*/

Generated on Wed Aug 23 17:49:23 2006 for GRASS by  doxygen 1.4.7