cats.c

Go to the documentation of this file.
00001 /**********************************************************************
00002  *
00003  * Code in this file works with category files.  There are two formats:
00004  * Pre 3.0 direct category encoding form:
00005  * 
00006  *    2 categories
00007  *    Map Title
00008  *    Elevation: 1000.00 to 1005.00 feet
00009  *    Elevation: 1005.00 to 1010.00 feet
00010  *    Elevation: 1010.00 to 1015.00 feet
00011  *
00012  * 3.0 format
00013  * 
00014  *    # 2 categories
00015  *    Map Title
00016  *    Elevation: $1.2 to $2.2 feet       ## Format Statement
00017  *    5.0 1000 5.0 1005                  ## Coefficients
00018  *
00019  * The coefficient line can be followed by explicit category labels
00020  * which override the format label generation.
00021  *    0:no data
00022  *    2:   .
00023  *    5:   .                             ## explicit category labels
00024  *    7:   .
00025  * explicit labels can be also of the form:
00026  *    5.5:5:9 label description
00027  *    or
00028  *    15:30  label description
00029  *
00030  * In the format line
00031  *   $1 refers to the value num*5.0+1000 (ie, using the first 2 coefficients)
00032  *   $2 refers to the value num*5.0+1005 (ie, using the last 2 coefficients)
00033  *
00034  *   $1.2 will print $1 with 2 decimal places.
00035  *
00036  * Also, the form $?xxx$yyy$ translates into yyy if the category is 1, xxx 
00037  * otherwise. The $yyy$ is optional. Thus
00038  *
00039  *   $1 meter$?s
00040  *
00041  * will become: 1 meter (for category 1)
00042  *              2 meters (for category 2), etc.
00043  *
00044  * The format and coefficients above would be used to generate the
00045  * following statement in creation of the format appropriate category
00046  * string for category "num":
00047  *
00048  *   sprintf(buff,"Elevation: %.2f to %.2f feet", num*5.0+1000, num*5.0*1005)
00049  *
00050  * Note: while both the format and coefficent lins must be present
00051  *       a blank line for the fmt will effectively suppress automatic
00052  *       label generation
00053  *
00054  * Note: quant rules of Categories structures are heavily dependant
00055  * on the fact that rules are stored in the same order they are entered.
00056  * since i-th rule and i-th label are entered at the same time, we
00057  * know that i-th rule maps fp range to i, thus we know for sure
00058  * that cats.labels[i] corresponds to i-th quant rule
00059  * 
00060  **********************************************************************
00061  *
00062  *  G_read_[raster]_cats (name, mapset, pcats)
00063  *      char *name                   name of cell file
00064  *      char *mapset                 mapset that cell file belongs to
00065  *      struct Categories *pcats     structure to hold category info
00066  *
00067  *  Reads the category information associated with cell file "name"
00068  *  in mapset "mapset" into the structure "pcats".
00069  *
00070  *  returns:    0  if successful
00071  *             -1  on fail
00072  *
00073  *  note:   a warning message is printed if the file is
00074  *          "missing" or "invalid".
00075  **********************************************************************
00076  *
00077  *  G_copy_raster_cats (pcats_to, pcats_from)
00078  *      struct Categories *pcats_to, *pcats_from
00079  *
00080  *  Allocates NEW space for quant rules and labels and copies
00081  *  all info from "from" cats to "to" cats
00082  *
00083  *  returns:    0  if successful
00084  *             -1  on fail
00085  *
00086  **********************************************************************
00087  *
00088  *  G_read_vector_cats (name, mapset, pcats)
00089  *      char *name                   name of vector file
00090  *      char *mapset                 mapset that vector file belongs to
00091  *      struct Categories *pcats     structure to hold category info
00092  *
00093  *
00094  *  returns:    0  if successful
00095  *             -1  on fail
00096  *
00097  *  note:   a warning message is printed if the file is
00098  *          "missing" or "invalid".
00099  **********************************************************************
00100  * Returns pointer to a string describing category.
00101  **********************************************************************
00102  *
00103  *  G_number_of_cats(name, mapset)
00104  *  returns the largest category number in the map.
00105  *  -1 on error
00106  *  WARING: do not use for fp maps!
00107  **********************************************************************
00108  *
00109  * char *
00110  * G_get_c/f/d_raster_cat (num, pcats)
00111  *      [F/D]CELL *val               pointer to cell value 
00112  *      struct Categories *pcats     structure to hold category info
00113  *
00114  * Returns pointer to a string describing category.
00115  *
00116  **********************************************************************
00117  *
00118  * char *
00119  * G_get_raster_cat (val, pcats, data_type)
00120  *      void *val               pointer to cell value 
00121  *      struct Categories *pcats     structure to hold category info
00122  *      RASTER_MAP_TYPE data_type    type of raster cell
00123  *
00124  * Returns pointer to a string describing category.
00125  *
00126  **********************************************************************
00127  *
00128  * char *
00129  * G_get_ith_c/f/d_raster_cat (pcats, i, rast1, rast2)
00130  *      [F/D]CELL *rast1, *rast2      cat range
00131  *      struct Categories *pcats     structure to hold category info
00132  *
00133  * Returns pointer to a string describing category.
00134  *
00135  **********************************************************************
00136  *
00137  * int
00138  * G_number_of_raster_cats (pcats)
00139  *      struct Categories *pcats     structure to hold category info
00140  *
00141  * Returns pcats->ncats number of labels
00142  *
00143  **********************************************************************
00144  *
00145  * char *
00146  * G_get_ith_raster_cat (pcats, i, rast1, rast2, data_type)
00147  *      void *rast1, *rast2      cat range
00148  *      struct Categories *pcats     structure to hold category info
00149  *      RASTER_MAP_TYPE data_type    type of raster cell
00150  *
00151  * Returns pointer to a string describing category.
00152  *
00153  **********************************************************************
00154  *
00155  * char *
00156  * G_get_[raster]_cats_title (pcats)
00157  *      struct Categories *pcats     structure to hold category info
00158  *
00159  * Returns pointer to a string with title
00160  *
00161  **********************************************************************
00162  *
00163  * G_init_cats (ncats, title, pcats)
00164  *      CELL ncats                   number of categories
00165  *      char *title                  cell title
00166  *      struct Categories *pcats     structure to hold category info
00167  *
00168  * Initializes the cats structure for subsequent calls to G_set_cat()
00169  **********************************************************************
00170  *
00171  * G_unmark_raster_cats (pcats)
00172  *      struct Categories *pcats     structure to hold category info
00173  *
00174  * initialize cats.marks: the statistics of how many values of map
00175  * have each label
00176  *
00177  **********************************************************************
00178  *
00179  * G_rewind_raster_cats (pcats)
00180  *      struct Categories *pcats     structure to hold category info
00181  *
00182  * after calll to this function G_get_next_marked_raster_cat() returns
00183  * rhe first marked cat label.
00184  *
00185  **********************************************************************
00186  *
00187  * char* G_get_next_marked_raster_cat(pcats, rast1, rast2, stats, data_type)
00188  *    struct Categories *pcats     structure to hold category info
00189  *    void *rast1, *rast2;         pointers to raster range
00190  *    long *stats;
00191  *    RASTER_MAP_TYPE  data_type
00192  *
00193  *    returns the next marked label.
00194  *    NULL if none found
00195  *
00196  **********************************************************************
00197  *
00198  * char* G_get_next_marked_f/d/craster_cat(pcats, rast1, rast2, stats)
00199  *    struct Categories *pcats     structure to hold category info
00200  *    [D/F]CELL *rast1, *rast2;    pointers to raster range
00201  *    long *stats;
00202  *
00203  *    returns the next marked label.
00204  *    NULL if none found
00205  *
00206  **********************************************************************
00207  *
00208  * G_mark_raster_cats (rast_row, ncols, pcats, data_type)
00209  *      void *raster_row;            raster row to update stats
00210  *      struct Categories *pcats     structure to hold category info
00211  *      RASTER_MAP_TYPE data_type;
00212  * Finds the index of label for each raster cell in a row, and
00213  * increases pcats->marks[index]
00214  * Note: if there are no explicit cats: only rules for cats, no 
00215  * marking is done.
00216  *
00217  **********************************************************************
00218  *
00219  * G_mark_c/d/f_raster_cats (rast_row, ncols, pcats)
00220  *      int ncols;
00221  *      [D?F]CELL *raster_row;            raster row to update stats
00222  *      struct Categories *pcats     structure to hold category info
00223  *
00224  * Finds the index of label for each raster cell in a row, and
00225  * increases pcats->marks[index]
00226  *
00227  **********************************************************************
00228  *
00229  * G_init_raster_cats (title, pcats)
00230  *      char *title                  cell title
00231  *      struct Categories *pcats     structure to hold category info
00232  *
00233  * Initializes the cats structure for subsequent calls to G_set_cat()
00234  *
00235  **********************************************************************
00236  *
00237  * G_set_[raster]_cats_fmt (fmt, m1, a1, m2, a2, pcats)
00238  *      char *fmt                    user form of the equation format
00239  *      float m1,a1,m2,a2            coefficients
00240  *      struct Categories *pcats     structure to hold category info
00241  *
00242  * configures the cats structure for the equation. Must be called
00243  * after G_init_cats().
00244  *
00245  **********************************************************************
00246  *
00247  * G_set_[raster]_cats_title (title, pcats)
00248  *      char *title                  cell file title
00249  *      struct Categories *pcats     structure holding category info
00250  *
00251  * Store title as cell file in cats structure
00252  * Returns nothing.
00253  *
00254  **********************************************************************
00255  *
00256  * G_set_cat (num, label, pcats)
00257  *      CELL num                     category number
00258  *      char *label                  category label
00259  *      struct Categories *pcats     structure to hold category info
00260  *
00261  * Adds the string buff to represent category "num" in category structure
00262  * pcats.
00263  *
00264  * Returns: 0 is cat is null value -1 too many cats, 1 ok.
00265  *
00266  **********************************************************************
00267  *
00268  * G_set_[f/d/c]_raster_cat (&val1, &val2, label, pcats)
00269  *      [D/F]CELL *val1, *val2;      pointers to raster values
00270  *      char *label                  category label
00271  *      struct Categories *pcats     structure to hold category info
00272  *
00273  * Adds the label for range val1 through val2 in category structure
00274  * pcats.
00275  *
00276  * Returns: 0 if cat is null value -1 too many cats, 1 ok.
00277  *
00278  **********************************************************************
00279  *
00280  * G_set_raster_cat (val1, val2, label, pcats, data_type)
00281  *      void *val1, *val2;           pointers to raster values
00282  *      char *label                  category label
00283  *      struct Categories *pcats     structure to hold category info
00284  *      RASTER_MAP_TYPE data_type    type of raster cell
00285  *
00286  * Adds the label for range val1 through val2 in category structure
00287  * pcats.
00288  *
00289  * Returns: 0 if cat is null value -1 too many cats, 1 ok.
00290  *
00291  **********************************************************************
00292  *
00293  *  G_write_[raster]_cats (name, pcats)
00294  *      char *name                   name of cell file
00295  *      struct Categories *pcats     structure holding category info
00296  *
00297  *  Writes the category information associated with cell file "name"
00298  *  into current mapset from the structure "pcats".
00299  *
00300  *   returns:    1  if successful
00301  *              -1  on fail
00302  **********************************************************************
00303  *
00304  *  G_write_vector_cats (name, pcats)
00305  *      char *name                   name of vector file
00306  *      struct Categories *pcats     structure holding category info
00307  *
00308  *  Writes the category information associated with vector file "name"
00309  *  into current mapset from the structure "pcats".
00310  *
00311  *   returns:    1  if successful
00312  *              -1  on fail
00313  **********************************************************************
00314  *
00315  * G_free_[raster]_cats (pcats)
00316  *      struct Categories *pcats     structure holding category info
00317  *
00318  * Releases memory allocated for the cats structure
00319  **********************************************************************/
00320   
00321 #include <stdlib.h>
00322 #include <string.h>
00323 #include <grass/gis.h>
00324 #include <grass/glocale.h>
00325 
00326 static int get_cond ( char **, char *, DCELL);
00327 static int get_fmt ( char **, char *, int *);
00328 static int cmp (const void *, const void *);
00329 
00330 
00345 int G_read_cats (
00346     char *name ,
00347     char *mapset ,
00348     struct Categories *pcats )
00349 {
00350     return G_read_raster_cats (name, mapset, pcats);
00351 }
00352     
00353 
00365 int G_read_raster_cats (
00366     char *name ,
00367     char *mapset ,
00368     struct Categories *pcats )
00369 {
00370     char *type;
00371 
00372     switch (G__read_cats ("cats", name, mapset, pcats, 1))
00373     {
00374     case -2:
00375             type = "missing";
00376             break;
00377     case -1:
00378             type = "invalid";
00379             break;
00380     default:
00381             return 0;
00382     }
00383 
00384     G_warning (_("category support for [%s] in mapset [%s] %s"),
00385                     name, mapset, type);
00386     return -1;
00387 }
00388 
00389 
00404 int G_read_vector_cats (
00405     char *name ,
00406     char *mapset ,
00407     struct Categories *pcats )
00408 {
00409     char *type;
00410 
00411     switch (G__read_cats ("dig_cats", name, mapset, pcats, 1))
00412     {
00413     case -2:
00414             type = "missing";
00415             break;
00416     case -1:
00417             type = "invalid";
00418             break;
00419     default:
00420             return 0;
00421     }
00422 
00423     G_warning (_("category support for vector file [%s] in mapset [%s] %s"),
00424                     name, mapset, type);
00425     return -1;
00426 }
00427 
00428 CELL G_number_of_cats (
00429     char *name ,
00430     char *mapset)
00431 {
00432     struct Range range;
00433     CELL min, max;
00434 
00435     /* return the max category number */
00436     if(G_read_range(name, mapset, &range) < 0)
00437         return -1;
00438     G_get_range_min_max(&range, &min, &max);
00439     if(G_is_c_null_value(&max)) max = 0;
00440     return max;
00441 }
00442 
00443 CELL G__read_cats (
00444     char *element,
00445     char *name ,
00446     char *mapset ,
00447     struct Categories *pcats,
00448     int full)
00449 {
00450     FILE *fd ;
00451     char buff[1024] ;
00452     CELL cat;
00453     DCELL val1, val2;
00454     int old=0, fp_map;
00455     long num=-1;
00456 
00457 
00458     if(strncmp(element, "dig", 3)== 0)
00459        fp_map = 0;
00460     else
00461        fp_map = G_raster_map_is_fp(name, mapset);
00462     
00463     if (!(fd = G_fopen_old (element, name, mapset)))
00464         return -2 ;
00465 
00466 /* Read the number of categories */
00467     if (G_getl(buff,sizeof buff,fd) == 0)
00468         goto error;
00469 
00470     if (sscanf ( buff, "# %ld"   , &num) == 1)
00471         old = 0;
00472     else if (sscanf ( buff, "%ld"   , &num) == 1)
00473         old = 1;
00474 
00475     if (!full)
00476     {
00477         fclose (fd);
00478         if(num < 0) return 0; /* coorect */
00479         return (CELL) num;
00480     }
00481 
00482 /* Read the title for the file */
00483     if (G_getl(buff,sizeof buff,fd) == 0)
00484         goto error;
00485     G_strip (buff);
00486 /*    G_ascii_check(buff) ; */
00487 
00488     G_init_raster_cats (buff, pcats);
00489     if(num >= 0) pcats->num = num;
00490 
00491     if (!old)
00492     {
00493         char fmt[256];
00494         float m1,a1,m2,a2;
00495         if (G_getl(fmt,sizeof fmt,fd) == 0)
00496                 goto error;
00497 /* next line contains equation coefficients */
00498         if (G_getl(buff,sizeof buff,fd) == 0)
00499                 goto error;
00500         if(sscanf(buff, "%f %f %f %f", &m1, &a1, &m2, &a2) != 4)
00501                 goto error;
00502         G_set_raster_cats_fmt (fmt, m1, a1, m2, a2, pcats);
00503     }
00504 
00505 /* Read all category names */
00506     for (cat=0;;cat++) 
00507     {
00508         char label[1024];
00509         if (G_getl(buff, sizeof buff, fd) == 0)
00510             break;
00511         if (old)
00512             G_set_cat (cat, buff, pcats) ;
00513         else
00514         {
00515             *label = 0;
00516             if (sscanf (buff, "%1s", label) != 1)
00517                 continue;
00518             if(*label == '#')
00519                 continue;
00520             *label = 0;
00521             /* for fp maps try to read a range of data */
00522             if (fp_map 
00523                 && sscanf (buff, "%lf:%lf:%[^\n]", &val1, &val2, label) == 3)
00524                 G_set_raster_cat (&val1, &val2, label, pcats, DCELL_TYPE);
00525             else if (sscanf (buff, "%d:%[^\n]", &cat, label) >= 1)
00526                 G_set_raster_cat (&cat, &cat, label, pcats, CELL_TYPE);
00527             else if (sscanf (buff, "%lf:%[^\n]", &val1, label) >= 1)
00528                 G_set_raster_cat (&val1, &val1, label, pcats, DCELL_TYPE);
00529             else goto error;
00530         }
00531     }
00532 
00533     fclose (fd);
00534     return 0 ;
00535 error:
00536     fclose (fd);
00537     return -1 ;
00538 }
00539 
00540 
00554 char *G_get_cats_title (struct Categories *pcats)
00555 {
00556    return G_get_raster_cats_title (pcats);
00557 }
00558 
00559 
00569 char *G_get_raster_cats_title (struct Categories *pcats)
00570 {
00571     static char *none = "";
00572     return pcats->title ? pcats->title : none;
00573 }
00574 
00575 
00591 char *G_get_cat (CELL num, struct Categories *pcats)
00592 {
00593     CELL tmp=num;
00594     return G_get_c_raster_cat(&tmp, pcats);
00595 }
00596 
00597 
00609 char *G_get_c_raster_cat ( CELL *rast, struct Categories *pcats)
00610 {
00611     return G_get_raster_cat(rast, pcats, CELL_TYPE);
00612 }
00613 
00614 
00626 char *G_get_f_raster_cat (
00627     FCELL *rast,
00628     struct Categories *pcats )
00629 {
00630     return G_get_raster_cat(rast, pcats, FCELL_TYPE);
00631 }
00632 
00633 
00645 char *G_get_d_raster_cat (
00646     DCELL *rast,
00647     struct Categories *pcats)
00648 {
00649     return G_get_raster_cat(rast, pcats, DCELL_TYPE);
00650 }
00651 
00652 
00665 char *G_get_raster_cat (
00666     void *rast,
00667     struct Categories *pcats ,
00668     RASTER_MAP_TYPE data_type)
00669 {
00670     static char label[1024] ;
00671     char *f, *l, *v;
00672     CELL i;
00673     DCELL val;
00674     float a[2];
00675     char fmt[30], value_str[30];
00676 
00677     if(G_is_null_value(rast, data_type)) 
00678     {
00679         sprintf(label, "no data");
00680         return label;
00681     }
00682 
00683 /* first search the list of labels */
00684     *label = 0;
00685     val = G_get_raster_value_d(rast, data_type);
00686     i = G_quant_get_cell_value(&pcats->q, val);
00687     /* DEBUG fprintf (stderr, "val %lf found i %d\n", val, i);*/
00688     if(!G_is_c_null_value(&i) && i < pcats->ncats)
00689     {
00690          if(pcats->labels[i] != NULL) return pcats->labels[i];
00691          return label;
00692     }
00693 
00694 /* generate the label */
00695     if ((f = pcats->fmt) == NULL)
00696         return label;
00697 
00698     a[0] = (float)val*pcats->m1+pcats->a1 ;
00699     a[1] = (float)val*pcats->m2+pcats->a2 ;
00700     l = label;
00701     while (*f)
00702     {
00703         if (*f == '$')
00704         {
00705             f++;
00706             if (*f == '$')
00707                 *l++ = *f++;
00708             else if (*f == '?')
00709             {
00710                 f++;
00711                 get_cond (&f, v = value_str, val);
00712                 while (*v)
00713                     *l++ = *v++;
00714             }
00715             else if (get_fmt (&f, fmt, &i))
00716             {
00717                 sprintf (v = value_str, fmt, a[i]);
00718                 while (*v)
00719                     *l++ = *v++;
00720             }
00721             else
00722                 *l++ = '$';
00723         }
00724         else
00725         {
00726             *l++ = *f++;
00727         }
00728     }
00729     *l = 0;
00730     return label;
00731 }
00732 
00733 
00749 int G_unmark_raster_cats (
00750       struct Categories *pcats)    /* structure to hold category info */
00751 {
00752       register int i;
00753       for(i=0; i<pcats->ncats; i++)
00754          pcats->marks[i] = 0;
00755       return 0;
00756 }
00757 
00758 
00773 int G_mark_c_raster_cats (
00774       CELL *rast_row,            /* raster row to update stats */
00775       int ncols,
00776       struct Categories *pcats)    /* structure to hold category info */
00777 {
00778       G_mark_raster_cats (rast_row, ncols, pcats, CELL_TYPE);
00779       return 0;
00780 }
00781 
00782 
00797 int G_mark_f_raster_cats (
00798       FCELL *rast_row,            /* raster row to update stats */
00799       int ncols,
00800       struct Categories *pcats)    /* structure to hold category info */
00801 {
00802       G_mark_raster_cats (rast_row, ncols, pcats, FCELL_TYPE);
00803       return 0;
00804 }
00805 
00806 
00821 int G_mark_d_raster_cats (
00822       DCELL *rast_row,            /* raster row to update stats */
00823       int ncols,
00824       struct Categories *pcats)    /* structure to hold category info */
00825 {
00826       G_mark_raster_cats (rast_row, ncols, pcats, DCELL_TYPE);
00827       return 0;
00828 }
00829 
00830 
00847 int G_mark_raster_cats (
00848       void *rast_row,            /* raster row to update stats */
00849       int ncols,
00850       struct Categories *pcats,    /* structure to hold category info */
00851       RASTER_MAP_TYPE data_type)
00852 {
00853    CELL i;
00854 
00855    while(ncols-- > 0)
00856    {
00857       i = G_quant_get_cell_value(&pcats->q, 
00858                  G_get_raster_value_d(rast_row, data_type));
00859       if(G_is_c_null_value(&i)) continue;
00860       if(i> pcats->ncats) return -1;
00861       pcats->marks[i]++;
00862       rast_row = G_incr_void_ptr(rast_row, G_raster_size(data_type));
00863    }
00864    return 1;
00865 }
00866 
00867 
00879 int G_rewind_raster_cats (struct Categories *pcats)
00880 {
00881     pcats->last_marked_rule = -1;
00882       return 0;
00883 }
00884 
00885 char *G_get_next_marked_d_raster_cat(
00886    struct Categories *pcats,    /* structure to hold category info */
00887    DCELL *rast1,DCELL *rast2,        /* pointers to raster range */
00888    long *count)
00889 {
00890     char *descr=NULL;
00891     int found, i;
00892 
00893     found = 0;
00894     /* pcats->ncats should be == G_quant_nof_rules(&pcats->q) */
00895     /* DEBUG
00896     fprintf (stderr, "last marked %d nrules %d\n", pcats->last_marked_rule, G_quant_nof_rules(&pcats->q));
00897     */
00898     for (i = pcats->last_marked_rule + 1; i < G_quant_nof_rules(&pcats->q); i++)
00899     {
00900         descr = G_get_ith_d_raster_cat(pcats, i, rast1, rast2);
00901         /* DEBUG fprintf (stderr, "%d %d\n", i, pcats->marks[i]); */
00902         if(pcats->marks[i]) 
00903         {
00904            found = 1;
00905            break;
00906         }
00907     }
00908 
00909     if(!found) return NULL;
00910 
00911     *count = pcats->marks[i];
00912     pcats->last_marked_rule = i;
00913     return descr;
00914 }
00915 
00916 char *G_get_next_marked_c_raster_cat(
00917    struct Categories *pcats,    /* structure to hold category info */
00918    CELL *rast1,CELL *rast2,        /* pointers to raster range */
00919    long *count)
00920 {
00921    return G_get_next_marked_raster_cat(pcats, rast1, rast2, count, CELL_TYPE);
00922 }
00923 
00924 char *G_get_next_marked_f_raster_cat(
00925    struct Categories *pcats,    /* structure to hold category info */
00926    FCELL *rast1,FCELL *rast2,        /* pointers to raster range */
00927    long *count)
00928 {
00929    return G_get_next_marked_raster_cat(pcats, rast1, rast2, count, FCELL_TYPE);
00930 }
00931 
00932 char *G_get_next_marked_raster_cat(
00933    struct Categories *pcats,    /* structure to hold category info */
00934    void *rast1,void *rast2,        /* pointers to raster range */
00935    long *count,
00936    RASTER_MAP_TYPE data_type)
00937 {
00938     DCELL val1, val2;
00939     char *lab;
00940 
00941     lab = G_get_next_marked_d_raster_cat(pcats, &val1, &val2, count);
00942     G_set_raster_value_d(rast1, val1, data_type);
00943     G_set_raster_value_d(rast2, val2, data_type);
00944     return lab;
00945 }
00946 
00947 static int get_fmt ( char **f, char *fmt, int *i)
00948 {
00949     char *ff;
00950 
00951     ff = *f;
00952     if (*ff == 0) return 0;
00953     if (*ff == '$')
00954     {
00955         *f = ff+1;
00956         return 0;
00957     }
00958     switch (*ff++)
00959     {
00960     case '1': *i = 0; break;
00961     case '2': *i = 1; break;
00962     default: return 0;
00963     }
00964     *fmt++ = '%';
00965     *fmt++ = '.';
00966     if (*ff++ != '.')
00967     {
00968         *f = ff-1;
00969         *fmt++ = '0';
00970         *fmt++ = 'f';
00971         *fmt = 0;
00972         return 1;
00973     }
00974     *fmt = '0';
00975     while (*ff >= '0' && *ff <= '9')
00976         *fmt++ = *ff++;
00977     *fmt++ = 'f';
00978     *fmt = 0;
00979     *f = ff;
00980     return 1;
00981 }
00982 
00983 static int get_cond ( char **f, char *value, DCELL val)
00984 {
00985     char *ff;
00986 
00987     ff = *f;
00988     if (val == 1.)
00989     {
00990         while (*ff)
00991             if (*ff++ == '$')
00992                 break;
00993     }
00994 
00995     while (*ff)
00996         if (*ff == '$')
00997         {
00998             ff++;
00999             break;
01000         }
01001         else
01002             *value++ = *ff++;
01003 
01004     if (val != 1.)
01005     {
01006         while (*ff)
01007             if (*ff++ == '$')
01008                 break;
01009     }
01010     *value = 0;
01011     *f = ff;
01012 
01013     return 0;
01014 }
01015 
01016 
01029 int G_set_cat (
01030     CELL num ,
01031     char *label ,
01032     struct Categories *pcats )
01033 {
01034     CELL tmp=num;
01035     return G_set_c_raster_cat(&tmp, &tmp, label, pcats);
01036 }
01037 
01038 
01051 int G_set_c_raster_cat (
01052     CELL *rast1,CELL *rast2,
01053     char *label ,
01054     struct Categories *pcats )
01055 {
01056     return G_set_raster_cat (rast1, rast2, label, pcats, CELL_TYPE);
01057 }
01058 
01059 
01072 int G_set_f_raster_cat (
01073     FCELL *rast1,FCELL *rast2,
01074     char *label ,
01075     struct Categories *pcats)
01076 {
01077     return G_set_raster_cat (rast1, rast2, label, pcats, FCELL_TYPE);
01078 }
01079 
01080 
01093 int G_set_d_raster_cat (
01094     DCELL *rast1,DCELL *rast2,
01095     char *label ,
01096     struct Categories *pcats )
01097 {
01098     long len;
01099     DCELL dtmp1, dtmp2;
01100     int i;
01101     char *descr;
01102 
01103 /* DEBUG fprintf(stderr,"G_set_d_raster_cat(rast1 = %p,rast2 = %p,label = '%s',pcats = %p)\n",
01104 rast1,rast2,label,pcats); */
01105     if(G_is_d_null_value(rast1)) return 0;
01106     if(G_is_d_null_value(rast2)) return 0;
01107     /* DEBUG fprintf (stderr, "G_set_d_raster_cat(): adding quant rule: %f %f %d %d\n", *rast1, *rast2, pcats->ncats, pcats->ncats); */
01108     /* the set_cat() functions are used in many places to reset the labels
01109        for the range (or cat) with existing label. In this case we don't
01110        want to store both rules with identical range even though the result
01111        of get_cat() will be correct, since it will use rule added later.
01112        we don't want to overuse memory and we don't want rules which are
01113        not used to be writen out in cats file. So we first look if
01114        the label for this range has been sen, and if it has, overwrite it */
01115 
01116     for(i=0; i< pcats->ncats; i++)
01117     {
01118        descr = G_get_ith_d_raster_cat(pcats, i, &dtmp1, &dtmp2);
01119        if((dtmp1==*rast1 && dtmp2==*rast2) 
01120         ||(dtmp1==*rast2 && dtmp2==*rast1))
01121        {
01122           if(pcats->labels[i] != NULL) G_free(pcats->labels[i]);
01123           pcats->labels[i] = G_store(label);
01124           G_newlines_to_spaces (pcats->labels[i]);
01125           G_strip (pcats->labels[i]);
01126           return 1;
01127        }
01128     }
01129     /* when rule for this range does not exist */
01130     /* DEBUG fprintf (stderr, "G_set_d_raster_cat(): New rule: adding %d %p\n", i, pcats->labels); */
01131     G_quant_add_rule(&pcats->q, *rast1, *rast2, pcats->ncats, pcats->ncats);
01132     pcats->ncats++;
01133     if(pcats->nalloc < pcats->ncats)
01134     {
01135     /* DEBUG fprintf (stderr, "G_set_d_raster_cat(): need more space nalloc = %d ncats = %d\n", pcats->nalloc,pcats->ncats); */
01136         len = (pcats->nalloc  + 256) * sizeof(char *);
01137     /* DEBUG fprintf (stderr, "G_set_d_raster_cat(): allocating %d labels(%d)\n", pcats->nalloc + 256,(int)len); */
01138         if (len != (int) len) /* make sure len doesn't overflow int */
01139         {
01140            pcats->ncats--;
01141            return -1;
01142         }
01143 /* DEBUG fprintf(stderr,"G_set_d_raster_cat(): pcats->nalloc = %d, pcats->labels = (%p), len = %d\n",pcats->nalloc,pcats->labels,(int)len); */
01144         if(pcats->nalloc) {
01145 /* DEBUG fprintf(stderr,"G_set_d_raster_cat(): Realloc-ing pcats->labels (%p)\n",pcats->labels); */
01146            pcats->labels = (char**) G_realloc((char*) pcats->labels, (int) len);
01147         } else {
01148 /* DEBUG fprintf(stderr,"G_set_d_raster_cat(): alloc-ing new labels pointer array\n"); */
01149            pcats->labels = (char**) G_malloc((int) len);
01150         }
01151 /* fflush(stderr); */
01152     /* DEBUG fprintf (stderr, "G_set_d_raster_cats(): allocating %d marks(%d)\n", pcats->nalloc + 256,(int)len); */
01153         len = (pcats->nalloc  + 256) * sizeof(int);
01154         if (len != (int) len) /* make sure len doesn't overflow int */
01155         {
01156            pcats->ncats--;
01157            return -1;
01158         }
01159         if(pcats->nalloc)
01160            pcats->marks = (int*) G_realloc((char *) pcats->marks, (int) len);
01161         else
01162            pcats->marks = (int*) G_malloc((int) len);
01163         pcats->nalloc += 256;
01164     }
01165     /* DEBUG fprintf(stderr,"G_set_d_raster_cats(): store new label\n"); */
01166     pcats->labels[pcats->ncats - 1] = G_store(label) ;
01167     G_newlines_to_spaces (pcats->labels[pcats->ncats - 1]);
01168     G_strip (pcats->labels[pcats->ncats - 1]);
01169     /* DEBUG
01170     fprintf (stderr, "%d %s\n", pcats->ncats - 1, pcats->labels[pcats->ncats - 1]);
01171     */
01172     /* updates cats.num = max cat values. This is really just used in old
01173        raster programs, and I am doing it for backwards cmpatibility (Olga) */
01174     if ((CELL) *rast1 > pcats->num)
01175                 pcats->num = (CELL) *rast1;
01176     if ((CELL) *rast2 > pcats->num)
01177                 pcats->num = (CELL) *rast2;
01178 /* DEBUG fprintf(stderr,"G_set_d_raster_cat(): done\n"); */
01179 /* DEBUG fflush(stderr); */
01180     return 1;
01181 }
01182 
01183 
01196 int G_set_raster_cat (
01197     void *rast1,void *rast2,
01198     char *label ,
01199     struct Categories *pcats ,
01200     RASTER_MAP_TYPE data_type)
01201 {
01202     DCELL val1, val2;
01203 
01204     val1 = G_get_raster_value_d(rast1, data_type);
01205     val2 = G_get_raster_value_d(rast2, data_type);
01206     return G_set_d_raster_cat (&val1, &val2, label, pcats);
01207 }
01208 
01209 
01223 int G_write_cats ( char *name , struct Categories *cats )
01224 {
01225     return G__write_cats ("cats", name, cats);
01226 }
01227 
01228 
01239 int G_write_raster_cats ( char *name , struct Categories *cats )
01240 {
01241     return G__write_cats ("cats", name, cats);
01242 }
01243 
01244 
01259 int G_write_vector_cats ( char *name , struct Categories *cats )
01260 {
01261     return G__write_cats ("dig_cats", name, cats);
01262 }
01263 
01264 int G__write_cats( char *element, char *name, struct Categories *cats)
01265 {
01266     FILE *fd ;
01267     int i, fp_map;
01268     char *descr;
01269     DCELL val1, val2;
01270     char str1[100], str2[100];
01271 
01272 /* DEBUG fprintf(stderr,"G__write_cats(*element = '%s', name = '%s', cats = %p\n",element,name,cats); */
01273     if (!(fd = G_fopen_new (element, name)))
01274         return -1;
01275 
01276 /* write # cats - note # indicate 3.0 or later */
01277     fprintf(fd,"# %ld categories\n", (long) cats->num);
01278 
01279 /* title */
01280     fprintf(fd,"%s\n", cats->title!=NULL?cats->title:"") ;
01281 
01282 /* write format and coefficients */
01283     fprintf(fd,"%s\n", cats->fmt!=NULL?cats->fmt:"") ;
01284     fprintf(fd,"%.2f %.2f %.2f %.2f\n",
01285             cats->m1, cats->a1, cats->m2, cats->a2) ;
01286 
01287     /* if the map is integer or if this is a vector map, sort labels */
01288     if(strncmp(element, "dig", 3)== 0)
01289        fp_map = 0;
01290     else
01291        fp_map = G_raster_map_is_fp(name, G_mapset());
01292 /* DEBUG fprintf(stderr,"G__write_cats(): fp_map = %d\n",fp_map); */
01293     if(!fp_map) G_sort_cats (cats);
01294 
01295     /* write the cat numbers:label */
01296     for (i = 0; i < G_quant_nof_rules(&cats->q); i++)
01297     {
01298         descr = G_get_ith_d_raster_cat(cats, i, &val1, &val2);
01299         if ((cats->fmt && cats->fmt[0])
01300         ||  (descr && descr[0]))
01301         {
01302             if(val1 == val2)
01303             {
01304                sprintf(str1, "%.10f", val1);
01305                G_trim_decimal (str1);
01306                fprintf(fd,"%s:%s\n", str1, 
01307                        descr!=NULL?descr:"");
01308             }
01309             else
01310             {
01311                sprintf(str1, "%.10f", val1);
01312                G_trim_decimal (str1);
01313                sprintf(str2, "%.10f", val2);
01314                G_trim_decimal (str2);
01315                fprintf(fd,"%s:%s:%s\n", str1, str2,  
01316                        descr!=NULL?descr:"");
01317             }
01318         }
01319     }
01320     fclose (fd) ;
01321 /* DEBUG fprintf(stderr,"G__write_cats(): done\n"); */
01322     return(1) ;
01323 }
01324 
01325 
01340 char *G_get_ith_d_raster_cat (
01341      struct Categories *pcats,
01342      int i,
01343      DCELL *rast1,DCELL *rast2)
01344 {
01345      int index;
01346      if(i > pcats->ncats) 
01347      {
01348          G_set_d_null_value(rast1, 1);
01349          G_set_d_null_value(rast2, 1);
01350          return "";
01351      }
01352      G_quant_get_ith_rule(&pcats->q, i, rast1, rast2, &index, &index);
01353      return pcats->labels[index];
01354 }
01355 
01356 
01371 char *G_get_ith_f_raster_cat (
01372      struct Categories *pcats,
01373      int i,
01374      void *rast1,void *rast2)
01375 {
01376      RASTER_MAP_TYPE data_type = FCELL_TYPE;  
01377      char *tmp;
01378      DCELL val1, val2;
01379      tmp = G_get_ith_d_raster_cat (pcats, i, &val1, &val2);
01380      G_set_raster_value_d(rast1, val1, data_type);
01381      G_set_raster_value_d(rast2, val2, data_type);
01382      return tmp;
01383 }
01384 
01385 
01400 char *G_get_ith_c_raster_cat (
01401      struct Categories *pcats,
01402      int i,
01403      void *rast1,void *rast2)
01404 {
01405      RASTER_MAP_TYPE data_type = CELL_TYPE;  
01406      char *tmp;
01407      DCELL val1, val2;
01408      tmp = G_get_ith_d_raster_cat (pcats, i, &val1, &val2);
01409      G_set_raster_value_d(rast1, val1, data_type);
01410      G_set_raster_value_d(rast2, val2, data_type);
01411      return tmp;
01412 }
01413 
01414 
01431 char *
01432 G_get_ith_raster_cat (struct Categories *pcats, int i, void *rast1, void *rast2, RASTER_MAP_TYPE data_type)  
01433 {
01434      char *tmp;
01435      DCELL val1, val2;
01436      tmp = G_get_ith_d_raster_cat (pcats, i, &val1, &val2);
01437      G_set_raster_value_d(rast1, val1, data_type);
01438      G_set_raster_value_d(rast2, val2, data_type);
01439      return tmp;
01440 }
01441 
01442 
01462 int G_init_cats (
01463     CELL num,
01464     char *title,
01465     struct Categories *pcats)
01466 {
01467     G_init_raster_cats (title, pcats);
01468     pcats->num = num;
01469       return 0;
01470 }
01471 
01472 
01485 int 
01486 G_init_raster_cats (char *title, struct Categories *pcats)
01487 {
01488     G_set_raster_cats_title (title, pcats);
01489     pcats->labels = NULL;
01490     pcats->nalloc = 0;
01491     pcats->ncats = 0;
01492     pcats->num = 0;
01493     pcats->fmt = NULL;
01494     pcats->m1 = 0.0;
01495     pcats->a1 = 0.0;
01496     pcats->m2 = 0.0;
01497     pcats->a2 = 0.0;
01498     pcats->last_marked_rule = -1;
01499     G_quant_init(&pcats->q);
01500       return 0;
01501 }
01502 
01503 
01515 int 
01516 G_set_cats_title (char *title, struct Categories *pcats)
01517 {
01518     G_set_raster_cats_title (title, pcats);
01519       return 0;
01520 }
01521 
01522 
01533 int 
01534 G_set_raster_cats_title (char *title, struct Categories *pcats)
01535 {
01536     if (title == NULL) title="";
01537     pcats->title = G_store (title);
01538     G_newlines_to_spaces (pcats->title);
01539     G_strip (pcats->title);
01540       return 0;
01541 }
01542 
01543 int G_set_cats_fmt (char *fmt, double m1, double a1, double m2, double a2, struct Categories *pcats)
01544 {
01545     G_set_raster_cats_fmt (fmt, m1, a1, m2, a2, pcats);
01546     return 0;
01547 }
01548 
01549 
01564 int G_set_raster_cats_fmt (char *fmt, double m1, double a1, double m2, double a2, struct Categories *pcats)
01565 {
01566     pcats->m1 = m1;
01567     pcats->a1 = a1;
01568     pcats->m2 = m2;
01569     pcats->a2 = a2;
01570 
01571     pcats->fmt = G_store (fmt);
01572     G_newlines_to_spaces (pcats->fmt);
01573     G_strip(pcats->fmt);
01574     return 0;
01575 }
01576 
01577 
01588 int G_free_cats (struct Categories *pcats)
01589 {
01590     G_free_raster_cats (pcats);
01591     return 0;
01592 }
01593 
01594 
01604 int G_free_raster_cats (struct Categories *pcats)
01605 {
01606     int i;
01607 
01608     if (pcats->title != NULL)
01609     {
01610         G_free (pcats->title);
01611         pcats->title = NULL;
01612     }
01613     if (pcats->fmt != NULL)
01614     {
01615         G_free (pcats->fmt);
01616         pcats->fmt = NULL;
01617     }
01618     if (pcats->ncats > 0)
01619     {
01620         for (i = 0; i < pcats->ncats; i++)
01621             if (pcats->labels[i] != NULL)
01622                 G_free (pcats->labels[i]);
01623         G_free (pcats->labels);
01624         G_free (pcats->marks);
01625         pcats->labels = NULL;
01626     }
01627     G_quant_free (&pcats->q);
01628     pcats->ncats = 0;
01629     pcats->nalloc = 0;
01630     return 0;
01631 }
01632 
01633 
01648 int 
01649 G_copy_raster_cats (struct Categories *pcats_to, struct Categories *pcats_from)
01650 {
01651    int i;
01652    char *descr;
01653    DCELL d1, d2;
01654  
01655    G_init_raster_cats(pcats_from->title, pcats_to);
01656    for(i = 0; i < pcats_from->ncats; i++)
01657    {
01658       descr = G_get_ith_d_raster_cat (pcats_from, i, &d1, &d2);
01659       G_set_d_raster_cat(&d1, &d2, descr, pcats_to);
01660    }
01661     return 0;
01662 }
01663 
01664 int G_number_of_raster_cats (struct Categories *pcats)
01665 {
01666   return pcats->ncats;
01667 }
01668 
01669 static struct Categories save_cats;
01670 
01671 int G_sort_cats (struct Categories *pcats)
01672 {
01673    int *indexes, i , ncats;
01674    char *descr;
01675    DCELL d1, d2;
01676 
01677    if (pcats->ncats <= 1) return -1;
01678 
01679    ncats = pcats->ncats;
01680 /* DEBUG fprintf(stderr,"G_sort_cats(): Copying to save cats buffer\n"); */
01681    G_copy_raster_cats(&save_cats, pcats);
01682    G_free_raster_cats(pcats);
01683 
01684    indexes = (int *) G_malloc(sizeof(int) * ncats);
01685    for(i = 0; i < ncats; i++)
01686        indexes[i] = i;
01687 
01688    qsort (indexes, ncats, sizeof (int), cmp);
01689    G_init_raster_cats(save_cats.title, pcats);
01690    for(i = 0; i < ncats; i++)
01691    {
01692       descr = G_get_ith_d_raster_cat (&save_cats, indexes[i], &d1, &d2);
01693 /* DEBUG fprintf(stderr,"G_sort_cats(): Write sorted cats, pcats = %p pcats->labels = %p\n",pcats,pcats->labels); */
01694       G_set_d_raster_cat(&d1, &d2, descr, pcats);
01695 /* DEBUG fflush(stderr); */
01696    }
01697    G_free_raster_cats(&save_cats);
01698 /* DEBUG fprintf(stderr,"G_sort_cats(): Done\n"); */
01699 /* fflush(stderr); */
01700 
01701    return 0;
01702 }
01703 
01704 static int cmp (const void *aa, const void *bb)
01705 {
01706     const int *a = aa, *b = bb;
01707     DCELL min_rast1, min_rast2, max_rast1, max_rast2; 
01708     CELL index;
01709     G_quant_get_ith_rule(&(save_cats.q), *a,
01710         &min_rast1, &max_rast1, &index, &index);
01711     G_quant_get_ith_rule(&(save_cats.q), *b,
01712         &min_rast2, &max_rast2, &index, &index);
01713     if(min_rast1 < min_rast2)
01714         return -1;
01715     if(min_rast1 > min_rast2)
01716         return 1;
01717     return 0;
01718 }
01719 
01720 

Generated on Wed Dec 19 14:59:05 2007 for GRASS by  doxygen 1.5.4