writeascii.c 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474
  1. /****************************************************************************
  2. *
  3. * MODULE: r.out.vtk
  4. *
  5. * AUTHOR(S): Original author
  6. * Soeren Gebbert soerengebbert@gmx.de
  7. * 08 23 2005 Berlin
  8. * PURPOSE: Converts raster maps into the VTK-Ascii format
  9. *
  10. * COPYRIGHT: (C) 2005 by the GRASS Development Team
  11. *
  12. * This program is free software under the GNU General Public
  13. * License (>=v2). Read the file COPYING that comes with GRASS
  14. * for details.
  15. *
  16. *****************************************************************************/
  17. #include <stdio.h>
  18. #include <stdlib.h>
  19. #include <string.h>
  20. #include <grass/gis.h>
  21. #include <grass/raster.h>
  22. #include <grass/glocale.h>
  23. #include <grass/config.h>
  24. #include "globaldefs.h"
  25. /*local prototypes */
  26. static double get_raster_value_as_double(int maptype, void *ptr,
  27. double nullval);
  28. /* ************************************************************************* */
  29. /* Get the value of the current raster pointer as double ******************* */
  30. /* ************************************************************************* */
  31. double get_raster_value_as_double(int MapType, void *ptr, double nullval)
  32. {
  33. double val = nullval;
  34. if (MapType == CELL_TYPE) {
  35. if (Rast_is_null_value(ptr, MapType)) {
  36. val = nullval;
  37. }
  38. else {
  39. val = *(CELL *) ptr;
  40. }
  41. }
  42. if (MapType == FCELL_TYPE) {
  43. if (Rast_is_null_value(ptr, MapType)) {
  44. val = nullval;
  45. }
  46. else {
  47. val = *(FCELL *) ptr;
  48. }
  49. }
  50. if (MapType == DCELL_TYPE) {
  51. if (Rast_is_null_value(ptr, MapType)) {
  52. val = nullval;
  53. }
  54. else {
  55. val = *(DCELL *) ptr;
  56. }
  57. }
  58. return val;
  59. }
  60. /* ************************************************************************* */
  61. /* Write the default VTK Header, Elevation is not supportet *************** */
  62. /* ************************************************************************* */
  63. void
  64. write_vtk_normal_header(FILE * fp, struct Cell_head region, double elevation,
  65. int type)
  66. {
  67. G_debug(3, _("write_vtk_normal_header: Writing VTK-Header"));
  68. /*Simple vtk ASCII header */
  69. fprintf(fp, "# vtk DataFile Version 3.0\n");
  70. fprintf(fp, "GRASS GIS 7 Export\n");
  71. fprintf(fp, "ASCII\n");
  72. fprintf(fp, "DATASET STRUCTURED_POINTS\n"); /*We are using the structured point dataset. */
  73. if (type)
  74. fprintf(fp, "DIMENSIONS %i %i %i\n", region.cols, region.rows, 1);
  75. else
  76. fprintf(fp, "DIMENSIONS %i %i %i\n", region.cols + 1, region.rows + 1,
  77. 1);
  78. fprintf(fp, "SPACING %lf %lf %lf\n", region.ew_res, region.ns_res, 0.0);
  79. if (type)
  80. fprintf(fp, "ORIGIN %lf %lf %lf\n",
  81. (region.west + region.ew_res / 2) - x_extent,
  82. (region.south + region.ns_res / 2) - y_extent, elevation);
  83. else
  84. fprintf(fp, "ORIGIN %lf %lf %lf\n", region.west - x_extent,
  85. region.south - y_extent, elevation);
  86. }
  87. /* ************************************************************************* */
  88. /* Write the Elevation VTK Header, Elevation is supportet ****************** */
  89. /* ************************************************************************* */
  90. void write_vtk_structured_elevation_header(FILE * fp, struct Cell_head region)
  91. {
  92. G_debug(3,
  93. _("write_vtk_structured_elevation_header: Writing VTK-Header"));
  94. /*Simple vtk ASCII header */
  95. fprintf(fp, "# vtk DataFile Version 3.0\n");
  96. fprintf(fp, "GRASS GIS 7 Export\n");
  97. fprintf(fp, "ASCII\n");
  98. fprintf(fp, "DATASET STRUCTURED_GRID\n"); /*We are using the structured grid dataset. */
  99. fprintf(fp, "DIMENSIONS %i %i %i\n", region.cols, region.rows, 1);
  100. fprintf(fp, "POINTS %i float\n", region.cols * region.rows); /*The Coordinates */
  101. }
  102. /* ************************************************************************* */
  103. /* Write the Rectilinear Elevtaion VTK Header, Elevation is supportet ****** */
  104. /* ************************************************************************* */
  105. void write_vtk_polygonal_elevation_header(FILE * fp, struct Cell_head region)
  106. {
  107. G_debug(3, _("write_vtk_polygonal_elevation_header: Writing VTK-Header"));
  108. /*Simple vtk ASCII header */
  109. fprintf(fp, "# vtk DataFile Version 3.0\n");
  110. fprintf(fp, "GRASS GIS 7 Export\n");
  111. fprintf(fp, "ASCII\n");
  112. fprintf(fp, "DATASET POLYDATA\n"); /*We are using polydataset. */
  113. fprintf(fp, "POINTS %i float\n", region.cols * region.rows);
  114. }
  115. /* ************************************************************************* */
  116. /* Write the CellDataHeader ************************************************ */
  117. /* ************************************************************************* */
  118. void write_vtk_celldata_header(FILE * fp, struct Cell_head region)
  119. {
  120. G_debug(3, _("write_vtk_celldata_header: Writing VTK-DataHeader"));
  121. fprintf(fp, "CELL_DATA %i\n", region.cols * region.rows);
  122. }
  123. /* ************************************************************************* */
  124. /* Write the PointDataHeader ************************************************ */
  125. /* ************************************************************************* */
  126. void write_vtk_pointdata_header(FILE * fp, struct Cell_head region)
  127. {
  128. G_debug(3, _("writeVTKPointHeader: Writing VTK-DataHeader"));
  129. fprintf(fp, "POINT_DATA %i\n", region.cols * region.rows);
  130. }
  131. /* ************************************************************************* */
  132. /* Write the VTK Structured Coordinates ************************************ */
  133. /* ************************************************************************* */
  134. void
  135. write_vtk_structured_coordinates(int fd, FILE * fp, char *varname,
  136. struct Cell_head region, int out_type,
  137. char *null_value, double scale, int dp)
  138. {
  139. int ncols = region.cols;
  140. int nrows = region.rows;
  141. int row, col;
  142. int rowcount = 0, colcount = 0;
  143. double nspos = 0.0, ewpos = 0.0;
  144. double nullvalue, value;
  145. void *ptr, *raster;
  146. G_debug(3, _("write_vtk_structured_coordinates: Writing Coordinates"));
  147. /*the nullvalue */
  148. if (!sscanf(null_value, "%lf", &nullvalue)) {
  149. G_warning("Null value is not valid, using 0 instead.");
  150. nullvalue = 0;
  151. }
  152. raster = Rast_allocate_buf(out_type);
  153. rowcount = 0;
  154. for (row = nrows - 1; row >= 0; row--) {
  155. colcount = 0;
  156. G_percent((row - nrows) * (-1), nrows, 2);
  157. Rast_get_row(fd, raster, row, out_type);
  158. nspos = region.ns_res / 2 + region.south + rowcount * region.ns_res;
  159. nspos -= y_extent;
  160. for (col = 0, ptr = raster; col < ncols;
  161. col++, ptr = G_incr_void_ptr(ptr, Rast_cell_size(out_type))) {
  162. ewpos =
  163. region.ew_res / 2 + region.west + colcount * region.ew_res;
  164. ewpos -= x_extent;
  165. value = get_raster_value_as_double(out_type, ptr, nullvalue);
  166. fprintf(fp, "%.*f %.*f %.*f\n", dp, ewpos, dp, nspos, dp,
  167. value * scale);
  168. colcount++;
  169. }
  170. rowcount++;
  171. }
  172. return;
  173. }
  174. /* ************************************************************************* */
  175. /* Write Polygonal Coordinates ********************************************* */
  176. /* ************************************************************************* */
  177. void
  178. write_vtk_polygonal_coordinates(int fd, FILE * fp, char *varname,
  179. struct Cell_head region, int out_type,
  180. char *null_value, double scale, int polytype,
  181. int dp)
  182. {
  183. int ncols = region.cols;
  184. int nrows = region.rows;
  185. int row, col;
  186. int rowcount = 0, colcount = 0;
  187. double nspos = 0.0, ewpos = 0.0;
  188. double value, nullvalue;
  189. void *ptr, *raster;
  190. int i, j, count;
  191. G_debug(3,
  192. _("write_vtk_polygonal_coordinates: Writing VTK Polygonal data"));
  193. /*the nullvalue */
  194. if (!sscanf(null_value, "%lf", &nullvalue)) {
  195. G_warning("Null value is not valid, using 0 instead.");
  196. nullvalue = 0;
  197. }
  198. /*First we are writing the coordinate points, the elevation cell is only used for the z coordinate */
  199. raster = Rast_allocate_buf(out_type);
  200. rowcount = 0;
  201. for (row = nrows - 1; row >= 0; row--) {
  202. colcount = 0;
  203. G_percent((row - nrows) * (-1), nrows, 10);
  204. Rast_get_row(fd, raster, row, out_type);
  205. nspos = region.ns_res / 2 + region.south + rowcount * region.ns_res;
  206. nspos -= y_extent;
  207. for (col = 0, ptr = raster; col < ncols;
  208. col++, ptr = G_incr_void_ptr(ptr, Rast_cell_size(out_type))) {
  209. ewpos =
  210. region.ew_res / 2 + region.west + colcount * region.ew_res;
  211. ewpos -= x_extent;
  212. value = get_raster_value_as_double(out_type, ptr, nullvalue);
  213. fprintf(fp, "%.*f %.*f %.*f\n", dp, ewpos, dp, nspos, dp,
  214. value * scale);
  215. colcount++;
  216. }
  217. rowcount++;
  218. }
  219. /*Now we need to write the Connectivity between the points */
  220. if (polytype == QUADS) { /*The default */
  221. /*If Datafiltering should be supportet, we use Polygons to represent the grid */
  222. fprintf(fp, "POLYGONS %i %i\n", (region.rows - 1) * (region.cols - 1),
  223. 5 * (region.rows - 1) * (region.cols - 1));
  224. /*We creat a grid of quads, the corners of the quads are the datapoints */
  225. for (i = 0; i < region.rows - 1; i++) {
  226. for (j = 0; j < region.cols - 1; j++) {
  227. fprintf(fp, "4 %i %i %i %i \n", i * region.cols + j,
  228. i * region.cols + j + 1,
  229. (i + 1) * region.cols + j + 1,
  230. (i + 1) * region.cols + j);
  231. }
  232. }
  233. }
  234. if (polytype == TRIANGLE_STRIPS) {
  235. /*TriangleStrips, take a look ate www.vtk.org for the definition of triangle_strips in vtk */
  236. /*If we use triangelestrips, the number of points per strip is equal to the double number of cols we have */
  237. fprintf(fp, "TRIANGLE_STRIPS %i %i\n", region.rows - 1,
  238. (region.rows - 1) + (region.rows - 1) * (2 * region.cols));
  239. /*For every Row-1 make a strip */
  240. for (i = 0; i < region.rows - 1; i++) {
  241. /*Number of Points */
  242. fprintf(fp, "%i ", region.cols * 2);
  243. /*Write the points */
  244. for (j = 0; j < region.cols; j++) {
  245. fprintf(fp, "%i %i ", i * region.cols + j,
  246. (i + 1) * region.cols + j);
  247. }
  248. fprintf(fp, "\n");
  249. }
  250. }
  251. if (polytype == VERTICES) {
  252. /*If the Data should be Triangulated by VTK, we use vertices to represent the grid */
  253. fprintf(fp, "VERTICES %i %i\n", region.rows,
  254. region.rows + (region.rows) * (region.cols));
  255. count = 0;
  256. for (i = 0; i < region.rows; i++) {
  257. fprintf(fp, "%i ", (region.cols));
  258. for (j = 0; j < region.cols; j++) {
  259. fprintf(fp, "%i ", count);
  260. count++;
  261. }
  262. fprintf(fp, "\n");
  263. }
  264. }
  265. return;
  266. }
  267. /* ************************************************************************* */
  268. /* Write the VTK Data ****************************************************** */
  269. /* ************************************************************************* */
  270. void
  271. write_vtk_data(int fd, FILE * fp, char *varname, struct Cell_head region,
  272. int out_type, char *null_value, int dp)
  273. {
  274. int ncols = region.cols;
  275. int nrows = region.rows;
  276. int row, col;
  277. double value, nullvalue;
  278. void *ptr, *raster;
  279. G_debug(3, _("write_vtk_data: Writing VTK-Data"));
  280. /*the nullvalue */
  281. if (!sscanf(null_value, "%lf", &nullvalue)) {
  282. G_warning("Null value is not valid, using 0 instead.");
  283. nullvalue = 0;
  284. }
  285. fprintf(fp, "SCALARS %s float 1\n", varname);
  286. fprintf(fp, "LOOKUP_TABLE default\n");
  287. raster = Rast_allocate_buf(out_type);
  288. for (row = nrows - 1; row >= 0; row--) {
  289. G_percent((row - nrows) * (-1), nrows, 10);
  290. Rast_get_row(fd, raster, row, out_type);
  291. for (col = 0, ptr = raster; col < ncols;
  292. col++, ptr = G_incr_void_ptr(ptr, Rast_cell_size(out_type))) {
  293. value = get_raster_value_as_double(out_type, ptr, nullvalue);
  294. fprintf(fp, "%.*f ", dp, value);
  295. }
  296. fprintf(fp, "\n");
  297. }
  298. return;
  299. }
  300. /* ************************************************************************* */
  301. /* Write the VTK RGB Image Data ******************************************** */
  302. /* ************************************************************************* */
  303. void
  304. write_vtk_rgb_image_data(int redfd, int greenfd, int bluefd, FILE * fp,
  305. const char *varname, struct Cell_head region,
  306. int out_type, int dp)
  307. {
  308. int ncols = region.cols;
  309. int nrows = region.rows;
  310. int row, col;
  311. void *redptr, *redraster;
  312. void *greenptr, *greenraster;
  313. void *blueptr, *blueraster;
  314. double r = 0.0, g = 0.0, b = 0.0;
  315. G_debug(3, _("write_vtk_rgb_image_data: Writing VTK-ImageData"));
  316. fprintf(fp, "COLOR_SCALARS %s 3\n", varname);
  317. redraster = Rast_allocate_buf(out_type);
  318. greenraster = Rast_allocate_buf(out_type);
  319. blueraster = Rast_allocate_buf(out_type);
  320. for (row = nrows - 1; row >= 0; row--) {
  321. G_percent((row - nrows) * (-1), nrows, 10);
  322. Rast_get_row(redfd, redraster, row, out_type);
  323. Rast_get_row(greenfd, greenraster, row, out_type);
  324. Rast_get_row(bluefd, blueraster, row, out_type);
  325. for (col = 0, redptr = redraster, greenptr = greenraster, blueptr =
  326. blueraster; col < ncols;
  327. col++, redptr =
  328. G_incr_void_ptr(redptr, Rast_cell_size(out_type)), greenptr =
  329. G_incr_void_ptr(greenptr, Rast_cell_size(out_type)), blueptr =
  330. G_incr_void_ptr(blueptr, Rast_cell_size(out_type))) {
  331. r = get_raster_value_as_double(out_type, redptr, 0.0);
  332. g = get_raster_value_as_double(out_type, greenptr, 0.0);
  333. b = get_raster_value_as_double(out_type, blueptr, 0.0);
  334. /*Test of valuerange, the data should be 1 byte gray values */
  335. if (r > 255 || g > 255 || b > 255 || r < 0 || g < 0 || b < 0) {
  336. G_warning(_("Wrong map values! Values should in between 0 and 255!\n"));
  337. fprintf(fp, "0 0 0 \n");
  338. }
  339. else {
  340. fprintf(fp, "%.*f %.*f %.*f \n", dp, r / 255, dp, g / 255, dp,
  341. b / 255);
  342. }
  343. }
  344. }
  345. return;
  346. }
  347. /* ************************************************************************* */
  348. /* Write the VTK Vector Data *********************************************** */
  349. /* ************************************************************************* */
  350. void
  351. write_vtk_vector_data(int xfd, int yfd, int zfd, FILE * fp,
  352. const char *varname, struct Cell_head region,
  353. int out_type, int dp)
  354. {
  355. int ncols = region.cols;
  356. int nrows = region.rows;
  357. int row, col;
  358. void *xptr, *xraster;
  359. void *yptr, *yraster;
  360. void *zptr, *zraster;
  361. double x = 0.0, y = 0.0, z = 0.0;
  362. G_debug(3, _("write_vtk_vector_data: Writing VTK-vector data"));
  363. fprintf(fp, "VECTORS %s float\n", varname);
  364. xraster = Rast_allocate_buf(out_type);
  365. yraster = Rast_allocate_buf(out_type);
  366. zraster = Rast_allocate_buf(out_type);
  367. for (row = nrows - 1; row >= 0; row--) {
  368. G_percent((row - nrows) * (-1), nrows, 10);
  369. Rast_get_row(xfd, xraster, row, out_type);
  370. Rast_get_row(yfd, yraster, row, out_type);
  371. Rast_get_row(zfd, zraster, row, out_type);
  372. for (col = 0, xptr = xraster, yptr = yraster, zptr =
  373. zraster; col < ncols;
  374. col++, xptr =
  375. G_incr_void_ptr(xptr, Rast_cell_size(out_type)), yptr =
  376. G_incr_void_ptr(yptr, Rast_cell_size(out_type)), zptr =
  377. G_incr_void_ptr(zptr, Rast_cell_size(out_type))) {
  378. x = get_raster_value_as_double(out_type, xptr, 0.0);
  379. y = get_raster_value_as_double(out_type, yptr, 0.0);
  380. z = get_raster_value_as_double(out_type, zptr, 0.0);
  381. fprintf(fp, "%.*f %.*f %.*f \n", dp, x, dp, y, dp, z);
  382. }
  383. }
  384. return;
  385. }