tilewrite.c 11 KB

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