range.c 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223
  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 <grass/glocale.h>
  10. #include "raster3d_intern.h"
  11. /*---------------------------------------------------------------------------*/
  12. void
  13. G3d_range_updateFromTile(G3D_Map * map, const void *tile, int rows, int cols,
  14. int depths, int xRedundant, int yRedundant,
  15. int zRedundant, int nofNum, int type)
  16. {
  17. int y, z, cellType;
  18. struct FPRange *range;
  19. range = &(map->range);
  20. cellType = G3d_g3dType2cellType(type);
  21. if (nofNum == map->tileSize) {
  22. Rast_row_update_fp_range(tile, map->tileSize, range, cellType);
  23. return;
  24. }
  25. if (xRedundant) {
  26. for (z = 0; z < depths; z++) {
  27. for (y = 0; y < rows; y++) {
  28. Rast_row_update_fp_range(tile, cols, range, cellType);
  29. tile = G_incr_void_ptr(tile, map->tileX * G3d_length(type));
  30. }
  31. if (yRedundant)
  32. tile =
  33. G_incr_void_ptr(tile,
  34. map->tileX * yRedundant *
  35. G3d_length(type));
  36. }
  37. return;
  38. }
  39. if (yRedundant) {
  40. for (z = 0; z < depths; z++) {
  41. Rast_row_update_fp_range(tile, map->tileX * rows, range, cellType);
  42. tile = G_incr_void_ptr(tile, map->tileXY * G3d_length(type));
  43. }
  44. return;
  45. }
  46. Rast_row_update_fp_range(tile, map->tileXY * depths, range, cellType);
  47. }
  48. /*---------------------------------------------------------------------------*/
  49. int
  50. G3d_readRange(const char *name, const char *mapset, struct FPRange *drange)
  51. /* adapted from Rast_read_fp_range */
  52. {
  53. int fd;
  54. char xdr_buf[100];
  55. DCELL dcell1, dcell2;
  56. XDR xdr_str;
  57. Rast_init_fp_range(drange);
  58. fd = -1;
  59. fd = G_open_old_misc(G3D_DIRECTORY, G3D_RANGE_ELEMENT, name, mapset);
  60. if (fd < 0) {
  61. G_warning(_("Unable to open range file for [%s in %s]"), name, mapset);
  62. return -1;
  63. }
  64. if (read(fd, xdr_buf, 2 * G3D_XDR_DOUBLE_LENGTH) != 2 * G3D_XDR_DOUBLE_LENGTH) {
  65. close(fd);
  66. G_warning(_("Error reading range file for [%s in %s]"), name, mapset);
  67. return 2;
  68. }
  69. xdrmem_create(&xdr_str, xdr_buf, (u_int) G3D_XDR_DOUBLE_LENGTH * 2,
  70. XDR_DECODE);
  71. /* if the f_range file exists, but empty */
  72. if (!xdr_double(&xdr_str, &dcell1) || !xdr_double(&xdr_str, &dcell2)) {
  73. close(fd);
  74. G_warning(_("Error reading range file for [%s in %s]"), name, mapset);
  75. return -1;
  76. }
  77. Rast_update_fp_range(dcell1, drange);
  78. Rast_update_fp_range(dcell2, drange);
  79. close(fd);
  80. return 1;
  81. }
  82. /*---------------------------------------------------------------------------*/
  83. /*!
  84. * \brief
  85. *
  86. * Loads the range into the range structure of <em>map</em>.
  87. *
  88. * \param map
  89. * \return 1 ... if successful
  90. * 0 ... otherwise.
  91. */
  92. int G3d_range_load(G3D_Map * map)
  93. {
  94. if (map->operation == G3D_WRITE_DATA)
  95. return 1;
  96. if (G3d_readRange(map->fileName, map->mapset, &(map->range)) == -1) {
  97. return 0;
  98. }
  99. return 1;
  100. }
  101. /*---------------------------------------------------------------------------*/
  102. /*!
  103. * \brief
  104. *
  105. * Returns in <em>min</em> and <em>max</em> the minimum and maximum values of
  106. * the range.
  107. *
  108. * \param map
  109. * \param min
  110. * \param max
  111. * \return void
  112. */
  113. void G3d_range_min_max(G3D_Map * map, double *min, double *max)
  114. {
  115. Rast_get_fp_range_min_max(&(map->range), min, max);
  116. }
  117. /*-------------------------------------------------------------------------*/
  118. static int writeRange(const char *name, struct FPRange *range)
  119. /* adapted from Rast_write_fp_range */
  120. {
  121. char xdr_buf[100];
  122. int fd;
  123. XDR xdr_str;
  124. fd = G_open_new_misc(G3D_DIRECTORY, G3D_RANGE_ELEMENT, name);
  125. if (fd < 0) {
  126. G_warning(_("Unable to open range file for <%s>"), name);
  127. return -1;
  128. }
  129. if (range->first_time) {
  130. /* if range hasn't been updated, write empty file meaning NULLs */
  131. close(fd);
  132. return 0;
  133. }
  134. xdrmem_create(&xdr_str, xdr_buf, (u_int) G3D_XDR_DOUBLE_LENGTH * 2,
  135. XDR_ENCODE);
  136. if (!xdr_double(&xdr_str, &(range->min)))
  137. goto error;
  138. if (!xdr_double(&xdr_str, &(range->max)))
  139. goto error;
  140. if (write(fd, xdr_buf, G3D_XDR_DOUBLE_LENGTH * 2) != G3D_XDR_DOUBLE_LENGTH * 2)
  141. goto error;
  142. close(fd);
  143. return 0;
  144. error:
  145. close(fd);
  146. G_remove_misc(G3D_DIRECTORY, G3D_RANGE_ELEMENT, name); /* remove the old file with this name */
  147. G_warning("can't write range file for [%s in %s]", name, G_mapset());
  148. return -1;
  149. }
  150. /*---------------------------------------------------------------------------*/
  151. /*!
  152. * \brief
  153. *
  154. * Writes the range which is stored in the range structure of <em>map</em>.
  155. * (This function is invoked automatically when a new file is closed).
  156. *
  157. * \param map
  158. * \return 1 ... if successful
  159. * 0 ... otherwise.
  160. */
  161. int G3d_range_write(G3D_Map * map)
  162. {
  163. char path[GPATH_MAX];
  164. G3d_filename(path, G3D_RANGE_ELEMENT, map->fileName, map->mapset);
  165. remove(path);
  166. if (writeRange(map->fileName, &(map->range)) == -1) {
  167. G3d_error("G3d_closeCellNew: error in writeRange");
  168. return 0;
  169. }
  170. return 1;
  171. }
  172. /*---------------------------------------------------------------------------*/
  173. int G3d_range_init(G3D_Map * map)
  174. {
  175. Rast_init_fp_range(&(map->range));
  176. return 0;
  177. }