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 <grass/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(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         /* if the f_range file exists, but empty */
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     /* if map is not integer, read quant rules, and get limits */
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 /* round */
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         /* if range file exists but empty */
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         /* if wrong format */
00300         if (count <= 0)
00301             goto error;
00302 
00303         for (n = 0 ; n < count ; n++)
00304         {
00305            /* if count==4, the range file is old (4.1) and 0's in it
00306               have to be ignored */
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     /* if range hasn't been updated */
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"); /* remove the old file with this name */
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     /* if range hasn't been updated, write empty file meaning Nulls */
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"); /* remove the old file with this name */
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 

Generated on Fri Nov 21 11:02:18 2008 for GRASS by  doxygen 1.5.1