open.c 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <fcntl.h>
  4. #include <sys/types.h>
  5. #include <unistd.h>
  6. #include <grass/raster3d.h>
  7. #include <grass/glocale.h>
  8. #include "raster3d_intern.h"
  9. /*---------------------------------------------------------------------------*/
  10. void *Rast3d_open_cell_old_no_header(const char *name, const char *mapset)
  11. {
  12. RASTER3D_Map *map;
  13. char xname[GNAME_MAX], xmapset[GMAPSET_MAX];
  14. Rast3d_init_defaults();
  15. if (!Rast3d_mask_open_old()) {
  16. Rast3d_error(_("Rast3d_open_cell_old_no_header: error in Rast3d_mask_open_old"));
  17. return (void *)NULL;
  18. }
  19. map = Rast3d_malloc(sizeof(RASTER3D_Map));
  20. if (map == NULL) {
  21. Rast3d_error(_("Rast3d_open_cell_old_no_header: error in Rast3d_malloc"));
  22. return (void *)NULL;
  23. }
  24. G_unqualified_name(name, mapset, xname, xmapset);
  25. map->fileName = G_store(xname);
  26. map->mapset = G_store(xmapset);
  27. map->data_fd = G_open_old_misc(RASTER3D_DIRECTORY, RASTER3D_CELL_ELEMENT, xname, xmapset);
  28. if (map->data_fd < 0) {
  29. Rast3d_error(_("Rast3d_open_cell_old_no_header: error in G_open_old"));
  30. return (void *)NULL;
  31. }
  32. Rast3d_range_init(map);
  33. Rast3d_mask_off(map);
  34. return map;
  35. }
  36. /*---------------------------------------------------------------------------*/
  37. /*!
  38. * \brief
  39. *
  40. * Opens existing g3d-file <em>name</em> in <em>mapset</em>.
  41. * Tiles are stored in memory with <em>type</em> which must be any of FCELL_TYPE,
  42. * DCELL_TYPE, or RASTER3D_TILE_SAME_AS_FILE. <em>cache</em> specifies the
  43. * cache-mode used and must be either RASTER3D_NO_CACHE, RASTER3D_USE_CACHE_DEFAULT,
  44. * RASTER3D_USE_CACHE_X, RASTER3D_USE_CACHE_Y, RASTER3D_USE_CACHE_Z,
  45. * RASTER3D_USE_CACHE_XY, RASTER3D_USE_CACHE_XZ, RASTER3D_USE_CACHE_YZ,
  46. * RASTER3D_USE_CACHE_XYZ, the result of <tt>Rast3d_cache_size_encode ()</tt> (cf.{g3d:G3d.cacheSizeEncode}), or any positive integer which
  47. * specifies the number of tiles buffered in the cache. <em>window</em> sets the
  48. * window-region for the map. It is either a pointer to a window structure or
  49. * RASTER3D_DEFAULT_WINDOW, which uses the window stored at initialization time or
  50. * set via <tt>Rast3d_set_window ()</tt> (cf.{g3d:G3d.setWindow}).
  51. * To modify the window for the map after it has already been opened use
  52. * <tt>Rast3d_set_window_map ()</tt> (cf.{g3d:G3d.setWindowMap}).
  53. * Returns a pointer to the cell structure ... if successful, NULL ...
  54. * otherwise.
  55. *
  56. * \param name
  57. * \param mapset
  58. * \param window
  59. * \param type
  60. * \param cache
  61. * \return void *
  62. */
  63. void *Rast3d_open_cell_old(const char *name, const char *mapset,
  64. RASTER3D_Region * window, int typeIntern, int cache)
  65. {
  66. RASTER3D_Map *map;
  67. int proj, zone;
  68. int compression, useRle, useLzw, type, tileX, tileY, tileZ;
  69. int rows, cols, depths, precision;
  70. double ew_res, ns_res, tb_res;
  71. int nofHeaderBytes, dataOffset, useXdr, hasIndex;
  72. char *ltmp, *unit;
  73. int vertical_unit;
  74. int version;
  75. double north, south, east, west, top, bottom;
  76. map = Rast3d_open_cell_old_no_header(name, mapset);
  77. if (map == NULL) {
  78. Rast3d_error(_("Rast3d_open_cell_old: error in Rast3d_open_cell_old_no_header"));
  79. return (void *)NULL;
  80. }
  81. if (lseek(map->data_fd, (long)0, SEEK_SET) == -1) {
  82. Rast3d_error(_("Rast3d_open_cell_old: can't rewind file"));
  83. return (void *)NULL;
  84. }
  85. if (!Rast3d_read_header(map,
  86. &proj, &zone,
  87. &north, &south, &east, &west, &top, &bottom,
  88. &rows, &cols, &depths,
  89. &ew_res, &ns_res, &tb_res,
  90. &tileX, &tileY, &tileZ,
  91. &type, &compression, &useRle, &useLzw,
  92. &precision, &dataOffset, &useXdr, &hasIndex, &unit, &vertical_unit,
  93. &version)) {
  94. Rast3d_error(_("Rast3d_open_cell_old: error in Rast3d_read_header"));
  95. return 0;
  96. }
  97. if (window == RASTER3D_DEFAULT_WINDOW)
  98. window = Rast3d_window_ptr();
  99. if (proj != window->proj) {
  100. Rast3d_error(_("Rast3d_open_cell_old: projection does not match window projection"));
  101. return (void *)NULL;
  102. }
  103. if (zone != window->zone) {
  104. Rast3d_error(_("Rast3d_open_cell_old: zone does not match window zone"));
  105. return (void *)NULL;
  106. }
  107. map->useXdr = useXdr;
  108. if (hasIndex) {
  109. /* see RASTER3D_openCell_new () for format of header */
  110. if ((!Rast3d_read_ints(map->data_fd, map->useXdr,
  111. &(map->indexLongNbytes), 1)) ||
  112. (!Rast3d_read_ints(map->data_fd, map->useXdr,
  113. &(map->indexNbytesUsed), 1))) {
  114. Rast3d_error(_("Rast3d_open_cell_old: can't read header"));
  115. return (void *)NULL;
  116. }
  117. /* if our long is to short to store offsets we can't read the file */
  118. if (map->indexNbytesUsed > sizeof(long))
  119. Rast3d_fatal_error(_("Rast3d_open_cell_old: index does not fit into long"));
  120. ltmp = Rast3d_malloc(map->indexLongNbytes);
  121. if (ltmp == NULL) {
  122. Rast3d_error(_("Rast3d_open_cell_old: error in Rast3d_malloc"));
  123. return (void *)NULL;
  124. }
  125. /* convert file long to long */
  126. if (read(map->data_fd, ltmp, map->indexLongNbytes) !=
  127. map->indexLongNbytes) {
  128. Rast3d_error(_("Rast3d_open_cell_old: can't read header"));
  129. return (void *)NULL;
  130. }
  131. Rast3d_long_decode(ltmp, &(map->indexOffset), 1, map->indexLongNbytes);
  132. Rast3d_free(ltmp);
  133. }
  134. nofHeaderBytes = dataOffset;
  135. if (typeIntern == RASTER3D_TILE_SAME_AS_FILE)
  136. typeIntern = type;
  137. if (!Rast3d_fill_header(map, RASTER3D_READ_DATA, compression, useRle, useLzw,
  138. type, precision, cache,
  139. hasIndex, map->useXdr, typeIntern,
  140. nofHeaderBytes, tileX, tileY, tileZ,
  141. proj, zone,
  142. north, south, east, west, top, bottom,
  143. rows, cols, depths, ew_res, ns_res, tb_res, unit, vertical_unit,
  144. version)) {
  145. Rast3d_error(_("Rast3d_open_cell_old: error in Rast3d_fill_header"));
  146. return (void *)NULL;
  147. }
  148. Rast3d_region_copy(&(map->window), window);
  149. Rast3d_adjust_region(&(map->window));
  150. Rast3d_get_nearest_neighbor_fun_ptr(&(map->resampleFun));
  151. return map;
  152. }
  153. /*---------------------------------------------------------------------------*/
  154. /*!
  155. * \brief
  156. *
  157. * Opens new g3d-file with <em>name</em> in the current mapset. Tiles
  158. * are stored in memory with <em>type</em> which must be one of FCELL_TYPE,
  159. * DCELL_TYPE, or RASTER3D_TILE_SAME_AS_FILE. <em>cache</em> specifies the
  160. * cache-mode used and must be either RASTER3D_NO_CACHE, RASTER3D_USE_CACHE_DEFAULT,
  161. * RASTER3D_USE_CACHE_X, RASTER3D_USE_CACHE_Y, RASTER3D_USE_CACHE_Z,
  162. * RASTER3D_USE_CACHE_XY, RASTER3D_USE_CACHE_XZ, RASTER3D_USE_CACHE_YZ,
  163. * RASTER3D_USE_CACHE_XYZ, the result of <tt>Rast3d_cache_size_encode ()</tt>
  164. * (cf.{g3d:G3d.cacheSizeEncode}), or any positive integer which
  165. * specifies the number of tiles buffered in the cache. <em>region</em> specifies
  166. * the 3d region.
  167. * Returns a pointer to the cell structure ... if successful,
  168. * NULL ... otherwise.
  169. *
  170. * \param name
  171. * \param type
  172. * \param cache
  173. * \param region
  174. * \return void *
  175. */
  176. void *Rast3d_open_cell_new(const char *name, int typeIntern, int cache,
  177. RASTER3D_Region * region)
  178. {
  179. RASTER3D_Map *map;
  180. int nofHeaderBytes, dummy = 0, compression, precision;
  181. long ldummy = 0;
  182. char xname[GNAME_MAX], xmapset[GMAPSET_MAX];
  183. Rast3d_init_defaults();
  184. if (!Rast3d_mask_open_old()) {
  185. Rast3d_error(_("Rast3d_open_cell_new: error in Rast3d_mask_open_old"));
  186. return (void *)NULL;
  187. }
  188. compression = g3d_do_compression;
  189. precision = g3d_precision;
  190. map = Rast3d_malloc(sizeof(RASTER3D_Map));
  191. if (map == NULL) {
  192. Rast3d_error(_("Rast3d_open_cell_new: error in Rast3d_malloc"));
  193. return (void *)NULL;
  194. }
  195. if (G_unqualified_name(name, G_mapset(), xname, xmapset) < 0) {
  196. G_warning(_("map <%s> is not in the current mapset"), name);
  197. return (void *)NULL;
  198. }
  199. map->fileName = G_store(xname);
  200. map->mapset = G_store(xmapset);
  201. map->tempName = G_tempfile();
  202. map->data_fd = open(map->tempName, O_RDWR | O_CREAT | O_TRUNC, 0666);
  203. if (map->data_fd < 0) {
  204. Rast3d_error(_("Rast3d_open_cell_new: could not open file"));
  205. return (void *)NULL;
  206. }
  207. Rast3d_make_mapset_map_directory(map->fileName);
  208. /* XDR support has been removed */
  209. map->useXdr = RASTER3D_NO_XDR;
  210. if (g3d_file_type == FCELL_TYPE) {
  211. if (precision > 23)
  212. precision = 23; /* 32 - 8 - 1 */
  213. else if (precision < -1)
  214. precision = 0;
  215. }
  216. else if (precision > 52)
  217. precision = 52; /* 64 - 11 - 1 */
  218. else if (precision < -1)
  219. precision = 0;
  220. /* no need to write trailing zeros */
  221. if ((typeIntern == FCELL_TYPE) && (g3d_file_type == DCELL_TYPE)) {
  222. if (precision == -1)
  223. precision = 23;
  224. else
  225. precision = RASTER3D_MIN(precision, 23);
  226. }
  227. if (compression == RASTER3D_NO_COMPRESSION)
  228. precision = RASTER3D_MAX_PRECISION;
  229. if (RASTER3D_HAS_INDEX) {
  230. map->indexLongNbytes = sizeof(long);
  231. /* at the beginning of the file write */
  232. /* nof bytes of "long" */
  233. /* max nof bytes used for index */
  234. /* position of index in file */
  235. /* the index is appended at the end of the file at closing time. since */
  236. /* we do not know this position yet we write dummy values */
  237. if ((!Rast3d_write_ints(map->data_fd, map->useXdr,
  238. &(map->indexLongNbytes), 1)) ||
  239. (!Rast3d_write_ints(map->data_fd, map->useXdr, &dummy, 1))) {
  240. Rast3d_error(_("Rast3d_open_cell_new: can't write header"));
  241. return (void *)NULL;
  242. }
  243. if (write(map->data_fd, &ldummy, map->indexLongNbytes) !=
  244. map->indexLongNbytes) {
  245. Rast3d_error(_("Rast3d_open_cell_new: can't write header"));
  246. return (void *)NULL;
  247. }
  248. }
  249. /* can't use a constant since this depends on sizeof (long) */
  250. nofHeaderBytes = lseek(map->data_fd, (long)0, SEEK_CUR);
  251. Rast3d_range_init(map);
  252. Rast3d_adjust_region(region);
  253. if (!Rast3d_fill_header(map, RASTER3D_WRITE_DATA, compression, 0, 0,
  254. g3d_file_type, precision, cache, RASTER3D_HAS_INDEX,
  255. map->useXdr, typeIntern, nofHeaderBytes,
  256. g3d_tile_dimension[0], g3d_tile_dimension[1],
  257. g3d_tile_dimension[2],
  258. region->proj, region->zone,
  259. region->north, region->south, region->east,
  260. region->west, region->top, region->bottom,
  261. region->rows, region->cols, region->depths,
  262. region->ew_res, region->ns_res, region->tb_res,
  263. g3d_unit_default, g3d_vertical_unit_default, RASTER3D_MAP_VERSION)) {
  264. Rast3d_error(_("Rast3d_open_cell_new: error in Rast3d_fill_header"));
  265. return (void *)NULL;
  266. }
  267. /*Set the map window to the map region */
  268. Rast3d_region_copy(&(map->window), region);
  269. /*Set the resampling function to nearest neighbor for data access */
  270. Rast3d_get_nearest_neighbor_fun_ptr(&(map->resampleFun));
  271. Rast3d_mask_off(map);
  272. return (void *)map;
  273. }