cats.c 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <sys/types.h>
  4. #include <unistd.h>
  5. #include <rpc/types.h>
  6. #include <rpc/xdr.h>
  7. #include <grass/gis.h>
  8. #include <grass/raster.h>
  9. #include "raster3d_intern.h"
  10. /*---------------------------------------------------------------------------*/
  11. /*!
  12. * \brief
  13. *
  14. * Writes the
  15. * categories stored in the <em>cats</em> structure into the categories file for
  16. * map <em>name</em> in the current mapset. See <em>Rast_write_cats</em>
  17. * (Raster_Category_File) for details and return values.
  18. *
  19. * \param name
  20. * \param cats
  21. * \return int
  22. */
  23. int Rast3d_write_cats(const char *name, struct Categories *cats)
  24. /* adapted from Rast_write_cats */
  25. {
  26. FILE *fd;
  27. int i;
  28. const char *descr;
  29. DCELL val1, val2;
  30. char str1[100], str2[100];
  31. fd = G_fopen_new_misc(RASTER3D_DIRECTORY, RASTER3D_CATS_ELEMENT, name);
  32. if (!fd)
  33. return -1;
  34. /* write # cats - note # indicate 3.0 or later */
  35. fprintf(fd, "# %ld categories\n", (long)cats->num);
  36. /* title */
  37. fprintf(fd, "%s\n", cats->title != NULL ? cats->title : "");
  38. /* write format and coefficients */
  39. fprintf(fd, "%s\n", cats->fmt != NULL ? cats->fmt : "");
  40. fprintf(fd, "%.2f %.2f %.2f %.2f\n",
  41. cats->m1, cats->a1, cats->m2, cats->a2);
  42. /* write the cat numbers:label */
  43. for (i = 0; i < Rast_quant_nof_rules(&cats->q); i++) {
  44. descr = Rast_get_ith_d_cat(cats, i, &val1, &val2);
  45. if ((cats->fmt && cats->fmt[0]) || (descr && descr[0])) {
  46. if (val1 == val2) {
  47. sprintf(str1, "%.10f", val1);
  48. G_trim_decimal(str1);
  49. fprintf(fd, "%s:%s\n", str1, descr != NULL ? descr : "");
  50. }
  51. else {
  52. sprintf(str1, "%.10f", val1);
  53. G_trim_decimal(str1);
  54. sprintf(str2, "%.10f", val2);
  55. G_trim_decimal(str2);
  56. fprintf(fd, "%s:%s:%s\n", str1, str2,
  57. descr != NULL ? descr : "");
  58. }
  59. }
  60. }
  61. fclose(fd);
  62. return 1;
  63. }
  64. /*---------------------------------------------------------------------------*/
  65. static int
  66. read_cats(const char *name, const char *mapset, struct Categories *pcats)
  67. /* adapted from G__read_cats */
  68. {
  69. FILE *fd;
  70. char buff[1024];
  71. CELL cat;
  72. DCELL val1, val2;
  73. int old;
  74. long num = -1;
  75. fd = G_fopen_old_misc(RASTER3D_DIRECTORY, RASTER3D_CATS_ELEMENT, name, mapset);
  76. if (!fd)
  77. return -2;
  78. /* Read the number of categories */
  79. if (G_getl(buff, sizeof(buff), fd) == 0)
  80. goto error;
  81. if (sscanf(buff, "# %ld", &num) == 1)
  82. old = 0;
  83. else if (sscanf(buff, "%ld", &num) == 1)
  84. old = 1;
  85. /* Read the title for the file */
  86. if (G_getl(buff, sizeof(buff), fd) == 0)
  87. goto error;
  88. G_strip(buff);
  89. Rast_init_cats(buff, pcats);
  90. if (num >= 0)
  91. pcats->num = num;
  92. if (!old) {
  93. char fmt[256];
  94. float m1, a1, m2, a2;
  95. if (G_getl(fmt, sizeof(fmt), fd) == 0)
  96. goto error;
  97. /* next line contains equation coefficients */
  98. if (G_getl(buff, sizeof(buff), fd) == 0)
  99. goto error;
  100. if (sscanf(buff, "%f %f %f %f", &m1, &a1, &m2, &a2) != 4)
  101. goto error;
  102. Rast_set_cats_fmt(fmt, m1, a1, m2, a2, pcats);
  103. }
  104. /* Read all category names */
  105. for (cat = 0;; cat++) {
  106. char label[1024];
  107. if (G_getl(buff, sizeof(buff), fd) == 0)
  108. break;
  109. if (old)
  110. Rast_set_c_cat(&cat, &cat, buff, pcats);
  111. else {
  112. *label = 0;
  113. if (sscanf(buff, "%1s", label) != 1)
  114. continue;
  115. if (*label == '#')
  116. continue;
  117. *label = 0;
  118. /* try to read a range of data */
  119. if (sscanf(buff, "%lf:%lf:%[^\n]", &val1, &val2, label) == 3)
  120. Rast_set_cat(&val1, &val2, label, pcats, DCELL_TYPE);
  121. else if (sscanf(buff, "%d:%[^\n]", &cat, label) >= 1)
  122. Rast_set_cat(&cat, &cat, label, pcats, CELL_TYPE);
  123. else if (sscanf(buff, "%lf:%[^\n]", &val1, label) >= 1)
  124. Rast_set_cat(&val1, &val1, label, pcats, DCELL_TYPE);
  125. else
  126. goto error;
  127. }
  128. }
  129. fclose(fd);
  130. return 0;
  131. error:
  132. fclose(fd);
  133. return -1;
  134. }
  135. /*---------------------------------------------------------------------------*/
  136. /*!
  137. * \brief
  138. *
  139. * Reads the categories file for map <em>name</em> in <em>mapset</em> and
  140. * stores the categories in the <em>pcats</em> structure. See <em>Rast_read_cats</em>
  141. * (Raster_Category_File) for details and return values.
  142. *
  143. * \param name
  144. * \param mapset
  145. * \param pcats
  146. * \return int
  147. */
  148. int
  149. Rast3d_read_cats(const char *name, const char *mapset, struct Categories *pcats)
  150. /* adapted from Rast_read_cats */
  151. {
  152. const char *type;
  153. switch (read_cats(name, mapset, pcats)) {
  154. case -2:
  155. type = "missing";
  156. break;
  157. case -1:
  158. type = "invalid";
  159. break;
  160. default:
  161. return 0;
  162. }
  163. G_warning("category support for [%s] in mapset [%s] %s",
  164. name, mapset, type);
  165. return -1;
  166. }