tilewrite.c 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <sys/types.h>
  4. #include <unistd.h>
  5. #include <grass/raster.h>
  6. #include "raster3d_intern.h"
  7. /*---------------------------------------------------------------------------*/
  8. static int
  9. Rast3d_tile2xdrTile(RASTER3D_Map * map, const void *tile, int rows, int cols,
  10. int depths, int xRedundant, int yRedundant, int zRedundant,
  11. int nofNum, int type)
  12. {
  13. int y, z;
  14. if (!Rast3d_init_copy_to_xdr(map, type)) {
  15. Rast3d_error("Rast3d_tile2xdrTile: error in Rast3d_init_copy_to_xdr");
  16. return 0;
  17. }
  18. if (nofNum == map->tileSize) {
  19. if (!Rast3d_copy_to_xdr(tile, map->tileSize)) {
  20. Rast3d_error("Rast3d_tile2xdrTile: error in Rast3d_copy_to_xdr");
  21. return 0;
  22. }
  23. return 1;
  24. }
  25. if (xRedundant) {
  26. for (z = 0; z < depths; z++) {
  27. for (y = 0; y < rows; y++) {
  28. if (!Rast3d_copy_to_xdr(tile, cols)) {
  29. Rast3d_error("Rast3d_tile2xdrTile: error in Rast3d_copy_to_xdr");
  30. return 0;
  31. }
  32. tile = G_incr_void_ptr(tile, map->tileX * Rast3d_length(type));
  33. }
  34. if (yRedundant)
  35. tile =
  36. G_incr_void_ptr(tile,
  37. map->tileX * yRedundant *
  38. Rast3d_length(type));
  39. }
  40. return 1;
  41. }
  42. if (yRedundant) {
  43. for (z = 0; z < depths; z++) {
  44. if (!Rast3d_copy_to_xdr(tile, map->tileX * rows)) {
  45. Rast3d_error("Rast3d_tile2xdrTile: error in Rast3d_copy_to_xdr");
  46. return 0;
  47. }
  48. tile = G_incr_void_ptr(tile, map->tileXY * Rast3d_length(type));
  49. }
  50. return 1;
  51. }
  52. if (!Rast3d_copy_to_xdr(tile, map->tileXY * depths)) {
  53. Rast3d_error("Rast3d_tile2xdrTile: error in Rast3d_copy_to_xdr");
  54. return 0;
  55. }
  56. return 1;
  57. }
  58. /*---------------------------------------------------------------------------*/
  59. static int Rast3d_writeTileUncompressed(RASTER3D_Map * map, int nofNum)
  60. {
  61. if (write(map->data_fd, xdr, map->numLengthExtern * nofNum) !=
  62. map->numLengthExtern * nofNum) {
  63. Rast3d_error("Rast3d_writeTileUncompressed: can't write file.");
  64. return 0;
  65. }
  66. return 1;
  67. }
  68. /*---------------------------------------------------------------------------*/
  69. static int Rast3d_writeTileCompressed(RASTER3D_Map * map, int nofNum)
  70. {
  71. if (!Rast3d_fpcompress_write_xdr_nums(map->data_fd, xdr, nofNum, map->precision,
  72. tmpCompress, map->type == FCELL_TYPE)) {
  73. Rast3d_error
  74. ("Rast3d_writeTileCompressed: error in Rast3d_fpcompress_write_xdr_nums");
  75. return 0;
  76. }
  77. return 1;
  78. }
  79. /*---------------------------------------------------------------------------*/
  80. /*---------------------------------------------------------------------------*/
  81. /* EXPORTED FUNCTIONS */
  82. /*---------------------------------------------------------------------------*/
  83. /*---------------------------------------------------------------------------*/
  84. /*!
  85. * \brief
  86. *
  87. *
  88. * Writes tile with index <em>tileIndex</em> to the file corresponding to <em>map</em>.
  89. * It is assumed that the cells in <em>tile</em> are of <em>type</em> which
  90. * must be one of FCELL_TYPE and DCELL_TYPE. The actual type used to write the
  91. * tile depends on the type specified at the time when <em>map</em> is initialized.
  92. * A tile can only be written once. Subsequent attempts to write the same tile
  93. * are ignored.
  94. *
  95. * \param map
  96. * \param tileIndex
  97. * \param tile
  98. * \param type
  99. * \return 1 ... if successful,
  100. * 2 ... if write request was ignored,
  101. * 0 ... otherwise.
  102. */
  103. int Rast3d_write_tile(RASTER3D_Map * map, int tileIndex, const void *tile, int type)
  104. {
  105. int rows, cols, depths, xRedundant, yRedundant, zRedundant, nofNum;
  106. /* valid tileIndex ? */
  107. if ((tileIndex > map->nTiles) || (tileIndex < 0))
  108. Rast3d_fatal_error("Rast3d_write_tile: tileIndex out of range");
  109. /* already written ? */
  110. if (map->index[tileIndex] != -1)
  111. return 2;
  112. /* save the file position */
  113. map->index[tileIndex] = lseek(map->data_fd, (long)0, SEEK_END);
  114. if (map->index[tileIndex] == -1) {
  115. Rast3d_error("Rast3d_write_tile: can't position file");
  116. return 0;
  117. }
  118. nofNum = Rast3d_compute_clipped_tile_dimensions(map, tileIndex,
  119. &rows, &cols, &depths,
  120. &xRedundant, &yRedundant,
  121. &zRedundant);
  122. Rast3d_range_update_from_tile(map, tile, rows, cols, depths,
  123. xRedundant, yRedundant, zRedundant, nofNum,
  124. type);
  125. if (!Rast3d_tile2xdrTile(map, tile, rows, cols, depths,
  126. xRedundant, yRedundant, zRedundant, nofNum, type)) {
  127. Rast3d_error("Rast3d_write_tile: error in Rast3d_tile2xdrTile");
  128. return 0;
  129. }
  130. if (map->compression == RASTER3D_NO_COMPRESSION) {
  131. if (!Rast3d_writeTileUncompressed(map, nofNum)) {
  132. Rast3d_error("Rast3d_write_tile: error in Rast3d_writeTileUncompressed");
  133. return 0;
  134. }
  135. }
  136. else { if (!Rast3d_writeTileCompressed(map, nofNum)) {
  137. Rast3d_error("Rast3d_write_tile: error in Rast3d_writeTileCompressed");
  138. return 0;
  139. }
  140. }
  141. /* compute the length */
  142. map->tileLength[tileIndex] = lseek(map->data_fd, (long)0, SEEK_END) -
  143. map->index[tileIndex];
  144. return 1;
  145. }
  146. /*---------------------------------------------------------------------------*/
  147. /*!
  148. * \brief
  149. *
  150. * Is equivalent to <tt>Rast3d_write_tile (map, tileIndex, tile, FCELL_TYPE).</tt>
  151. *
  152. * \param map
  153. * \param tileIndex
  154. * \param tile
  155. * \return int
  156. */
  157. int Rast3d_write_tile_float(RASTER3D_Map * map, int tileIndex, const void *tile)
  158. {
  159. int status;
  160. if ((status = Rast3d_write_tile(map, tileIndex, tile, FCELL_TYPE)))
  161. return status;
  162. Rast3d_error("Rast3d_write_tile_float: error in Rast3d_write_tile");
  163. return 0;
  164. }
  165. /*---------------------------------------------------------------------------*/
  166. /*!
  167. * \brief
  168. *
  169. * Is equivalent to <tt>Rast3d_write_tile (map, tileIndex, tile, DCELL_TYPE).</tt>
  170. *
  171. * \param map
  172. * \param tileIndex
  173. * \param tile
  174. * \return int
  175. */
  176. int Rast3d_write_tile_double(RASTER3D_Map * map, int tileIndex, const void *tile)
  177. {
  178. int status;
  179. if ((status = Rast3d_write_tile(map, tileIndex, tile, DCELL_TYPE)))
  180. return status;
  181. Rast3d_error("Rast3d_write_tile_double: error in Rast3d_write_tile");
  182. return 0;
  183. }
  184. /*---------------------------------------------------------------------------*/
  185. /* CACHE-MODE-ONLY FUNCTIONS */
  186. /*---------------------------------------------------------------------------*/
  187. /*!
  188. * \brief
  189. *
  190. * Writes the tile with
  191. * <em>tileIndex</em> to the file corresponding to <em>map</em> and removes the tile
  192. * from the cache (in non-cache mode the buffer provided by the map-structure is
  193. * written).
  194. * If this tile has already been written before the write request is ignored.
  195. * If the tile was never referred to before the invokation of Rast3d_flush_tile, a
  196. * tile filled with NULL-values is written.
  197. *
  198. * \param map
  199. * \param tileIndex
  200. * \return 1 ... if successful,
  201. * 0 ... otherwise.
  202. */
  203. int Rast3d_flush_tile(RASTER3D_Map * map, int tileIndex)
  204. {
  205. const void *tile;
  206. tile = Rast3d_get_tile_ptr(map, tileIndex);
  207. if (tile == NULL) {
  208. Rast3d_error("Rast3d_flush_tile: error in Rast3d_get_tile_ptr");
  209. return 0;
  210. }
  211. if (!Rast3d_write_tile(map, tileIndex, tile, map->typeIntern)) {
  212. Rast3d_error("Rast3d_flush_tile: error in Rast3d_write_tile");
  213. return 0;
  214. }
  215. if (!Rast3d__remove_tile(map, tileIndex)) {
  216. Rast3d_error("Rast3d_flush_tile: error in Rast3d__remove_tile");
  217. return 0;
  218. }
  219. return 1;
  220. }
  221. /*---------------------------------------------------------------------------*/
  222. #ifndef MIN
  223. #define MIN(a,b) (a < b ? a : b)
  224. #define MAX(a,b) (a > b ? a : b)
  225. #endif
  226. /*!
  227. * \brief
  228. *
  229. * Writes the tiles with tile-coordinates
  230. * contained in the axis-parallel cube with vertices <em>(xMin, yMin, zMin)</em>
  231. * and <em>(xMax, yMax, zMax</em>). Tiles which are not stored in the cache are
  232. * written as NULL-tiles. Write attempts for tiles which have already been
  233. * written earlier are ignored.
  234. *
  235. * \param map
  236. * \param xMin
  237. * \param yMin
  238. * \param zMin
  239. * \param xMax
  240. * \param yMax
  241. * \param zMax
  242. * \return 1 ... if successful,
  243. * 0 ... otherwise.
  244. */
  245. int
  246. Rast3d_flush_tile_cube(RASTER3D_Map * map, int xMin, int yMin, int zMin, int xMax,
  247. int yMax, int zMax)
  248. {
  249. int x, y, z;
  250. if (!map->useCache)
  251. Rast3d_fatal_error
  252. ("Rast3d_flush_tile_cube: function invalid in non-cache mode");
  253. for (x = xMin; x <= xMax; x++)
  254. for (y = yMin; y <= yMax; y++)
  255. for (z = zMin; z <= zMax; z++)
  256. if (!Rast3d_flush_tile(map, Rast3d_tile2tile_index(map, x, y, z))) {
  257. Rast3d_error("Rast3d_flush_tile_cube: error in Rast3d_flush_tile");
  258. return 0;
  259. }
  260. return 1;
  261. }
  262. /*---------------------------------------------------------------------------*/
  263. /*!
  264. * \brief
  265. *
  266. * Writes those tiles for which
  267. * <em>every</em> cell has coordinate contained in the axis-parallel cube
  268. * defined by the vertices with cell-coordinates <em>(xMin, yMin, zMin)</em>
  269. * and <em>(xMax, yMax, zMax)</em>.
  270. * Tiles which are not stored in the cache are written as NULL-tiles.
  271. * Write attempts for tiles which have already been written earlier are
  272. * ignored.
  273. *
  274. * \param map
  275. * \param xMin
  276. * \param yMin
  277. * \param zMin
  278. * \param xMax
  279. * \param yMax
  280. * \param zMax
  281. * \return 1 ... if successful,
  282. * 0 ... otherwise.
  283. */
  284. int
  285. Rast3d_flush_tiles_in_cube(RASTER3D_Map * map, int xMin, int yMin, int zMin, int xMax,
  286. int yMax, int zMax)
  287. {
  288. int xTileMin, yTileMin, zTileMin, xTileMax, yTileMax, zTileMax;
  289. int xOffs, yOffs, zOffs;
  290. int regionMaxX, regionMaxY, regionMaxZ;
  291. if (!map->useCache)
  292. Rast3d_fatal_error
  293. ("Rast3d_flush_tiles_in_cube: function invalid in non-cache mode");
  294. /*AV*/
  295. /*BEGIN OF ORIGINAL CODE */
  296. /*
  297. * Rast3d_get_coords_map (map, &regionMaxX, &regionMaxY, &regionMaxZ);
  298. */
  299. /*AV*/
  300. /* BEGIN OF MY CODE */
  301. Rast3d_get_coords_map(map, &regionMaxY, &regionMaxX, &regionMaxZ);
  302. /* END OF MY CODE */
  303. if ((xMin < 0) && (xMax < 0))
  304. Rast3d_fatal_error("Rast3d_flush_tiles_in_cube: coordinate out of Range");
  305. if ((xMin >= regionMaxX) && (xMax >= regionMaxX))
  306. Rast3d_fatal_error("Rast3d_flush_tiles_in_cube: coordinate out of Range");
  307. xMin = MIN(MAX(0, xMin), regionMaxX - 1);
  308. if ((yMin < 0) && (yMax < 0))
  309. Rast3d_fatal_error("Rast3d_flush_tiles_in_cube: coordinate out of Range");
  310. if ((yMin >= regionMaxY) && (yMax >= regionMaxY))
  311. Rast3d_fatal_error("Rast3d_flush_tiles_in_cube: coordinate out of Range");
  312. yMin = MIN(MAX(0, yMin), regionMaxY - 1);
  313. if ((zMin < 0) && (zMax < 0))
  314. Rast3d_fatal_error("Rast3d_flush_tiles_in_cube: coordinate out of Range");
  315. if ((zMin >= regionMaxZ) && (zMax >= regionMaxZ))
  316. Rast3d_fatal_error("Rast3d_flush_tiles_in_cube: coordinate out of Range");
  317. zMin = MIN(MAX(0, zMin), regionMaxZ - 1);
  318. Rast3d_coord2tile_coord(map, xMin, yMin, zMin,
  319. &xTileMin, &yTileMin, &zTileMin,
  320. &xOffs, &yOffs, &zOffs);
  321. if (xOffs != 0)
  322. xTileMin++;
  323. if (yOffs != 0)
  324. yTileMin++;
  325. if (zOffs != 0)
  326. zTileMin++;
  327. Rast3d_coord2tile_coord(map, xMax + 1, yMax + 1, zMax + 1,
  328. &xTileMax, &yTileMax, &zTileMax,
  329. &xOffs, &yOffs, &zOffs);
  330. xTileMax--;
  331. yTileMax--;
  332. zTileMax--;
  333. if (!Rast3d_flush_tile_cube(map, xTileMin, yTileMin, zTileMin,
  334. xTileMax, yTileMax, zTileMax)) {
  335. Rast3d_error("Rast3d_flush_tiles_in_cube: error in Rast3d_flush_tile_cube");
  336. return 0;
  337. }
  338. return 1;
  339. }
  340. #undef MIN
  341. #undef MAX
  342. /*---------------------------------------------------------------------------*/