writeVTK.c 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957
  1. /***************************************************************************
  2. *
  3. * MODULE: v.out.vtk
  4. * AUTHOR(S): Soeren Gebbert
  5. *
  6. * PURPOSE: v.out.vtk: writes ASCII VTK file
  7. * this module is based on v.out.ascii
  8. * COPYRIGHT: (C) 2000 by the GRASS Development Team
  9. *
  10. * This program is free software under the GNU General Public
  11. * License (>=v2). Read the file COPYING that comes with GRASS
  12. * for details.
  13. *
  14. ****************************************************************************/
  15. #include <stdlib.h>
  16. #include <grass/vector.h>
  17. #include <grass/dbmi.h>
  18. #include <grass/gis.h>
  19. #include <grass/glocale.h>
  20. #include "writeVTK.h"
  21. #include "local_proto.h"
  22. /*Prototype */
  23. /*Formated coordinates output */
  24. static void write_point_coordinates(struct line_pnts *Points, int dp,
  25. double scale, FILE * ascii);
  26. /* ************************************************************************* */
  27. /* This function writes the vtk points and coordinates ********************* */
  28. /* ************************************************************************* */
  29. int write_vtk_points(FILE * ascii, struct Map_info *Map, VTKInfo * info,
  30. int *types, int typenum, int dp, double scale)
  31. {
  32. int type, cur, i, k, centroid;
  33. int pointoffset = 0;
  34. int lineoffset = 0;
  35. int polygonoffset = 0;
  36. static struct line_pnts *Points;
  37. struct line_cats *Cats;
  38. Points = Vect_new_line_struct(); /* init line_pnts struct */
  39. Cats = Vect_new_cats_struct();
  40. G_message("Writing coordinates ...");
  41. /*For every available vector type */
  42. for (k = 0; k < typenum; k++) {
  43. /*POINT KERNEL CENTROID */
  44. if (types[k] == GV_POINT || types[k] == GV_KERNEL ||
  45. types[k] == GV_CENTROID) {
  46. /*Get the number of the points to generate */
  47. info->typeinfo[types[k]]->pointoffset = pointoffset;
  48. /*count the number of line_nodes and lines */
  49. Vect_rewind(Map);
  50. while (1) {
  51. if (-1 == (type = Vect_read_next_line(Map, Points, Cats)))
  52. break;
  53. if (type == -2) /* EOF */
  54. break;
  55. if (type == types[k]) {
  56. info->typeinfo[types[k]]->numpoints++;
  57. }
  58. }
  59. pointoffset += info->typeinfo[types[k]]->numpoints;
  60. info->typeinfo[types[k]]->numvertices =
  61. info->typeinfo[types[k]]->numpoints;
  62. info->maxnumvertices += info->typeinfo[types[k]]->numpoints;
  63. info->maxnumpoints += info->typeinfo[types[k]]->numpoints;
  64. /*
  65. * printf("Points Type %i Number %i offset %i\n", types[k],
  66. * info->typeinfo[types[k]]->numpoints,
  67. * info->typeinfo[types[k]]->pointoffset);
  68. */
  69. }
  70. }
  71. for (k = 0; k < typenum; k++) {
  72. /*LINE BOUNDARY */
  73. if (types[k] == GV_LINE || types[k] == GV_BOUNDARY) {
  74. info->typeinfo[types[k]]->pointoffset = pointoffset;
  75. info->typeinfo[types[k]]->lineoffset = lineoffset;
  76. /*count the number of line_nodes and lines */
  77. Vect_rewind(Map);
  78. while (1) {
  79. if (-1 == (type = Vect_read_next_line(Map, Points, Cats)))
  80. break;
  81. if (type == -2) /* EOF */
  82. break;
  83. if (type == types[k]) {
  84. info->typeinfo[types[k]]->numpoints += Points->n_points;
  85. info->typeinfo[types[k]]->numlines++;
  86. }
  87. }
  88. pointoffset += info->typeinfo[types[k]]->numpoints;
  89. lineoffset += info->typeinfo[types[k]]->lineoffset;
  90. info->maxnumpoints += info->typeinfo[types[k]]->numpoints;
  91. info->maxnumlinepoints += info->typeinfo[types[k]]->numpoints;
  92. info->maxnumlines += info->typeinfo[types[k]]->numlines;
  93. /*
  94. * printf("Lines Type %i Number %i offset %i\n", types[k],
  95. * info->typeinfo[types[k]]->numlines,
  96. * info->typeinfo[types[k]]->lineoffset);
  97. */
  98. }
  99. }
  100. for (k = 0; k < typenum; k++) {
  101. /*FACE */
  102. if (types[k] == GV_FACE) {
  103. info->typeinfo[types[k]]->pointoffset = pointoffset;
  104. info->typeinfo[types[k]]->polygonoffset = polygonoffset;
  105. /*count the number of line_nodes and lines */
  106. Vect_rewind(Map);
  107. while (1) {
  108. if (-1 == (type = Vect_read_next_line(Map, Points, Cats)))
  109. break;
  110. if (type == -2) /* EOF */
  111. break;
  112. if (type == types[k]) {
  113. info->typeinfo[types[k]]->numpoints += Points->n_points;
  114. info->typeinfo[types[k]]->numpolygons++;
  115. }
  116. }
  117. pointoffset += info->typeinfo[types[k]]->numpoints;
  118. polygonoffset += info->typeinfo[types[k]]->numpolygons;
  119. info->maxnumpoints += info->typeinfo[types[k]]->numpoints;
  120. info->maxnumpolygonpoints += info->typeinfo[types[k]]->numpoints;
  121. info->maxnumpolygons += info->typeinfo[types[k]]->numpolygons;
  122. /*
  123. * printf("Polygons Type %i Number %i offset %i\n", types[k],
  124. * info->typeinfo[types[k]]->numpolygons,
  125. * info->typeinfo[types[k]]->polygonoffset);
  126. */
  127. }
  128. }
  129. for (k = 0; k < typenum; k++) {
  130. /*AREA */
  131. if (types[k] == GV_AREA) {
  132. info->typeinfo[types[k]]->numpolygons = Vect_get_num_areas(Map);
  133. info->typeinfo[types[k]]->pointoffset = pointoffset;
  134. info->typeinfo[types[k]]->polygonoffset = polygonoffset;
  135. /*Count the coordinate points */
  136. Vect_rewind(Map);
  137. for (i = 1; i <= info->typeinfo[types[k]]->numpolygons; i++) {
  138. centroid = Vect_get_area_centroid(Map, i);
  139. if (centroid > 0) {
  140. Vect_read_line(Map, NULL, Cats, centroid);
  141. }
  142. Vect_get_area_points(Map, i, Points);
  143. info->typeinfo[types[k]]->numpoints += Points->n_points;
  144. }
  145. pointoffset += info->typeinfo[types[k]]->numpoints;
  146. polygonoffset += info->typeinfo[types[k]]->numpolygons;
  147. info->maxnumpoints += info->typeinfo[types[k]]->numpoints;
  148. info->maxnumpolygonpoints += info->typeinfo[types[k]]->numpoints;
  149. info->maxnumpolygons += info->typeinfo[types[k]]->numpolygons;
  150. /*
  151. * printf("Polygons Type %i Number %i offset %i\n", types[k],
  152. * info->typeinfo[types[k]]->numpolygons,
  153. * info->typeinfo[types[k]]->polygonoffset);
  154. */
  155. }
  156. }
  157. /*
  158. * printf("Maxnum points %i \n", info->maxnumpoints);
  159. * printf("Maxnum vertices %i \n", info->maxnumvertices);
  160. * printf("Maxnum lines %i \n", info->maxnumlines);
  161. * printf("Maxnum line points %i \n", info->maxnumlinepoints);
  162. * printf("Maxnum polygons %i \n", info->maxnumpolygons);
  163. * printf("Maxnum polygon points %i \n", info->maxnumpolygonpoints);
  164. */
  165. /*break if nothing to generate */
  166. if (info->maxnumpoints == 0)
  167. G_fatal_error(_("No coordinates to generate the output! Maybe an empty vector type chosen?"));
  168. /************************************************/
  169. /*Write the coordinates into the vtk ascii file */
  170. /************************************************/
  171. fprintf(ascii, "POINTS %i float\n", info->maxnumpoints);
  172. /*For every available vector type */
  173. for (k = 0; k < typenum; k++) {
  174. /*POINT KERNEL CENTROID */
  175. if (types[k] == GV_POINT || types[k] == GV_KERNEL ||
  176. types[k] == GV_CENTROID) {
  177. Vect_rewind(Map);
  178. /*Write the coordinates */
  179. cur = 0;
  180. while (1) {
  181. if (cur <= info->typeinfo[types[k]]->numpoints)
  182. G_percent(cur, info->typeinfo[types[k]]->numpoints, 2);
  183. if (-1 == (type = Vect_read_next_line(Map, Points, Cats)))
  184. break;
  185. if (type == -2) /* EOF */
  186. break;
  187. if (type == types[k]) {
  188. write_point_coordinates(Points, dp, scale, ascii);
  189. if (Cats->n_cats == 0)
  190. info->typeinfo[types[k]]->generatedata = 0; /*No data generation */
  191. }
  192. cur++;
  193. }
  194. }
  195. }
  196. for (k = 0; k < typenum; k++) {
  197. /*LINE BOUNDARY */
  198. if (types[k] == GV_LINE || types[k] == GV_BOUNDARY) {
  199. Vect_rewind(Map);
  200. cur = 0;
  201. while (1) {
  202. if (cur <= info->typeinfo[types[k]]->numlines)
  203. G_percent(cur, info->typeinfo[types[k]]->numlines, 2);
  204. if (-1 == (type = Vect_read_next_line(Map, Points, Cats)))
  205. break;
  206. if (type == -2) /* EOF */
  207. break;
  208. if (type == types[k]) {
  209. write_point_coordinates(Points, dp, scale, ascii);
  210. }
  211. cur++;
  212. }
  213. }
  214. }
  215. for (k = 0; k < typenum; k++) {
  216. /* FACE */
  217. if (types[k] == GV_FACE) {
  218. Vect_rewind(Map);
  219. cur = 0;
  220. while (1) {
  221. if (cur <= info->typeinfo[types[k]]->numpolygons)
  222. G_percent(cur, info->typeinfo[types[k]]->numpolygons, 2);
  223. if (-1 == (type = Vect_read_next_line(Map, Points, Cats)))
  224. break;
  225. if (type == -2) /* EOF */
  226. break;
  227. if (type == types[k]) {
  228. write_point_coordinates(Points, dp, scale, ascii);
  229. }
  230. cur++;
  231. }
  232. }
  233. }
  234. for (k = 0; k < typenum; k++) {
  235. /* AREA */
  236. if (types[k] == GV_AREA) {
  237. Vect_rewind(Map);
  238. for (i = 1; i <= info->typeinfo[types[k]]->numpolygons; i++) {
  239. centroid = Vect_get_area_centroid(Map, i);
  240. if (centroid > 0) {
  241. Vect_read_line(Map, NULL, Cats, centroid);
  242. }
  243. Vect_get_area_points(Map, i, Points);
  244. write_point_coordinates(Points, dp, scale, ascii);
  245. }
  246. }
  247. }
  248. return 1;
  249. }
  250. /* ************************************************************************* */
  251. /* This function writes the vtk cells ************************************** */
  252. /* ************************************************************************* */
  253. int write_vtk_cells(FILE * ascii, struct Map_info *Map, VTKInfo * info,
  254. int *types, int typenum)
  255. {
  256. int type, i, j, k, centroid;
  257. static struct line_pnts *Points;
  258. struct line_cats *Cats;
  259. /*The keywords may only be written once! */
  260. int vertkeyword = 1;
  261. int linekeyword = 1;
  262. int polykeyword = 1;
  263. G_message("Writing vtk cells ...");
  264. Points = Vect_new_line_struct(); /* init line_pnts struct */
  265. Cats = Vect_new_cats_struct();
  266. /*For every available vector type */
  267. for (k = 0; k < typenum; k++) {
  268. /*POINT KERNEL CENTROID */
  269. if (types[k] == GV_POINT || types[k] == GV_KERNEL ||
  270. types[k] == GV_CENTROID) {
  271. Vect_rewind(Map);
  272. /*Write the vertices */
  273. if (info->typeinfo[types[k]]->numpoints > 0) {
  274. if (vertkeyword) {
  275. fprintf(ascii, "VERTICES %i %i\n", info->maxnumvertices,
  276. info->maxnumvertices * 2);
  277. vertkeyword = 0;
  278. }
  279. for (i = 0; i < info->typeinfo[types[k]]->numpoints; i++) {
  280. fprintf(ascii, "1 %i\n",
  281. i + info->typeinfo[types[k]]->pointoffset);
  282. }
  283. fprintf(ascii, "\n");
  284. }
  285. }
  286. }
  287. for (k = 0; k < typenum; k++) {
  288. /*LINE BOUNDARY */
  289. if (types[k] == GV_LINE || types[k] == GV_BOUNDARY) {
  290. Vect_rewind(Map);
  291. if (info->maxnumlines > 0) {
  292. if (linekeyword) {
  293. fprintf(ascii, "LINES %i %i\n", info->maxnumlines,
  294. info->maxnumlinepoints + info->maxnumlines);
  295. linekeyword = 0;
  296. }
  297. Vect_rewind(Map);
  298. i = 0;
  299. while (1) {
  300. if (-1 == (type = Vect_read_next_line(Map, Points, Cats)))
  301. break;
  302. if (type == -2) /* EOF */
  303. break;
  304. if (type == types[k]) {
  305. /*Check for data generation */
  306. if (Cats->n_cats == 0)
  307. info->typeinfo[types[k]]->generatedata = 0; /*No data generation */
  308. fprintf(ascii, "%i", Points->n_points);
  309. while (Points->n_points--) {
  310. fprintf(ascii, " %i",
  311. i +
  312. info->typeinfo[types[k]]->pointoffset);
  313. i++;
  314. }
  315. fprintf(ascii, "\n");
  316. }
  317. }
  318. }
  319. }
  320. }
  321. for (k = 0; k < typenum; k++) {
  322. /*LINE BOUNDARY FACE */
  323. if (types[k] == GV_FACE) {
  324. Vect_rewind(Map);
  325. if (info->maxnumpolygons > 0) {
  326. if (polykeyword) {
  327. fprintf(ascii, "POLYGONS %i %i\n",
  328. info->maxnumpolygons,
  329. info->maxnumpolygonpoints + info->maxnumpolygons);
  330. polykeyword = 0;
  331. }
  332. Vect_rewind(Map);
  333. i = 0;
  334. while (1) {
  335. if (-1 == (type = Vect_read_next_line(Map, Points, Cats)))
  336. break;
  337. if (type == -2) /* EOF */
  338. break;
  339. if (type == types[k]) {
  340. /*Check for data generation */
  341. if (Cats->n_cats == 0)
  342. info->typeinfo[types[k]]->generatedata = 0; /*No data generation */
  343. fprintf(ascii, "%i", Points->n_points);
  344. while (Points->n_points--) {
  345. fprintf(ascii, " %i",
  346. i +
  347. info->typeinfo[types[k]]->pointoffset);
  348. i++;
  349. }
  350. fprintf(ascii, "\n");
  351. }
  352. }
  353. }
  354. }
  355. }
  356. for (k = 0; k < typenum; k++) {
  357. /*AREA */
  358. if (types[k] == GV_AREA) {
  359. Vect_rewind(Map);
  360. if (info->maxnumpolygons > 0) {
  361. if (polykeyword) {
  362. fprintf(ascii, "POLYGONS %i %i\n",
  363. info->maxnumpolygons,
  364. info->maxnumpolygonpoints + info->maxnumpolygons);
  365. polykeyword = 0;
  366. }
  367. j = 0;
  368. for (i = 1; i <= info->typeinfo[types[k]]->numpolygons; i++) {
  369. centroid = Vect_get_area_centroid(Map, i);
  370. if (centroid > 0) {
  371. Vect_read_line(Map, NULL, Cats, centroid);
  372. }
  373. Vect_get_area_points(Map, i, Points);
  374. /*Check for data generation */
  375. if (Cats->n_cats == 0)
  376. info->typeinfo[types[k]]->generatedata = 0; /*No data generation */
  377. fprintf(ascii, "%i", Points->n_points);
  378. while (Points->n_points--) {
  379. fprintf(ascii, " %i",
  380. j + info->typeinfo[types[k]]->pointoffset);
  381. j++;
  382. }
  383. fprintf(ascii, "\n");
  384. }
  385. }
  386. }
  387. }
  388. return 1;
  389. }
  390. /* ************************************************************************* */
  391. /* This function writes the categories as vtk cell data ******************** */
  392. /* ************************************************************************* */
  393. int write_vtk_cat_data(FILE * ascii, struct Map_info *Map, VTKInfo * info,
  394. int layer, int *types, int typenum, int dp)
  395. {
  396. int type, cat, i, k, centroid;
  397. static struct line_pnts *Points;
  398. struct line_cats *Cats;
  399. /*The keywords may only be written once! */
  400. int numcelldata =
  401. info->maxnumvertices + info->maxnumlines + info->maxnumpolygons;
  402. Points = Vect_new_line_struct(); /* init line_pnts struct */
  403. Cats = Vect_new_cats_struct();
  404. G_message("Writing category cell data ...");
  405. if (numcelldata > 0) {
  406. /*Write the pointdata */
  407. fprintf(ascii, "CELL_DATA %i\n", numcelldata);
  408. fprintf(ascii, "SCALARS cat_%s int 1\n", Map->name);
  409. fprintf(ascii, "LOOKUP_TABLE default\n");
  410. /*For every available vector type */
  411. for (k = 0; k < typenum; k++) {
  412. /*POINT KERNEL CENTROID */
  413. if (types[k] == GV_POINT || types[k] == GV_KERNEL ||
  414. types[k] == GV_CENTROID) {
  415. Vect_rewind(Map);
  416. while (1) {
  417. if (-1 == (type = Vect_read_next_line(Map, Points, Cats)))
  418. break;
  419. if (type == -2) /* EOF */
  420. break;
  421. if (type == types[k]) {
  422. Vect_cat_get(Cats, layer, &cat);
  423. fprintf(ascii, " %d", cat);
  424. }
  425. }
  426. }
  427. }
  428. for (k = 0; k < typenum; k++) {
  429. /*LINE BOUNDARY */
  430. if (types[k] == GV_LINE || types[k] == GV_BOUNDARY) {
  431. Vect_rewind(Map);
  432. while (1) {
  433. if (-1 == (type = Vect_read_next_line(Map, Points, Cats)))
  434. break;
  435. if (type == -2) /* EOF */
  436. break;
  437. if (type == types[k]) {
  438. Vect_cat_get(Cats, layer, &cat);
  439. fprintf(ascii, " %d", cat);
  440. }
  441. }
  442. }
  443. }
  444. for (k = 0; k < typenum; k++) {
  445. /*FACE */
  446. if (types[k] == GV_FACE) {
  447. Vect_rewind(Map);
  448. while (1) {
  449. if (-1 == (type = Vect_read_next_line(Map, Points, Cats)))
  450. break;
  451. if (type == -2) /* EOF */
  452. break;
  453. if (type == types[k]) {
  454. Vect_cat_get(Cats, layer, &cat);
  455. fprintf(ascii, " %d", cat);
  456. }
  457. }
  458. }
  459. }
  460. for (k = 0; k < typenum; k++) {
  461. /*AREA */
  462. if (types[k] == GV_AREA) {
  463. Vect_rewind(Map);
  464. for (i = 1; i <= info->typeinfo[types[k]]->numpolygons; i++) {
  465. centroid = Vect_get_area_centroid(Map, i);
  466. if (centroid > 0) {
  467. Vect_read_line(Map, NULL, Cats, centroid);
  468. }
  469. Vect_cat_get(Cats, layer, &cat);
  470. fprintf(ascii, " %d", cat);
  471. }
  472. }
  473. }
  474. fprintf(ascii, "\n");
  475. }
  476. return 1;
  477. }
  478. /*
  479. Reads the attribute field "name" for current cat and returns the value as a string
  480. or NULL on error
  481. Memory for the result string is allocated by this function and must be free'd by
  482. the caller.
  483. */
  484. char *get_att(char *name, int cat, struct field_info *Fi, dbDriver * Driver,
  485. int ncol)
  486. {
  487. char buf[2000];
  488. int more;
  489. dbTable *Table;
  490. static dbString dbstring;
  491. dbColumn *Column;
  492. dbCursor cursor;
  493. char *retval;
  494. static int first = 1;
  495. if (first) {
  496. db_init_string(&dbstring);
  497. first = 0;
  498. }
  499. sprintf(buf, "SELECT %s FROM %s WHERE %s = %d", name, Fi->table, Fi->key, cat);
  500. db_set_string(&dbstring, buf);
  501. if (db_open_select_cursor(Driver, &dbstring, &cursor, DB_SEQUENTIAL) !=
  502. DB_OK) {
  503. G_fatal_error(_("Cannot select attributes for cat = %d"), cat);
  504. }
  505. if (db_fetch(&cursor, DB_NEXT, &more) != DB_OK)
  506. G_fatal_error(_("Unable to fetch data from table"));
  507. Table = db_get_cursor_table(&cursor);
  508. Column = db_get_table_column(Table, 0);
  509. if (!strcmp(name, db_get_column_name(Column))) {
  510. db_convert_column_value_to_string(Column, &dbstring);
  511. retval =
  512. G_malloc(sizeof(char) *
  513. (strlen(db_get_string(&dbstring)) + 1));
  514. retval = G_store(db_get_string(&dbstring));
  515. db_close_cursor(&cursor);
  516. return (retval);
  517. }
  518. db_close_cursor(&cursor);
  519. return (NULL);
  520. }
  521. /* ************************************************************************* */
  522. /* This function writes numerical attribute table fields as VTK scalars **** */
  523. /* ************************************************************************* */
  524. int write_vtk_db_data(FILE * ascii, struct Map_info *Map, VTKInfo * info,
  525. int layer, int *types, int typenum, int dp)
  526. {
  527. int type, cat, i, k, centroid;
  528. struct line_cats *Cats;
  529. /*The keywords may only be written once! */
  530. int numcelldata =
  531. info->maxnumvertices + info->maxnumlines + info->maxnumpolygons;
  532. /* attribute table info */
  533. int ncol = 0, colsqltype, colctype, num_atts, cur_att, progress;
  534. struct field_info *Fi = NULL;
  535. dbDriver *Driver = NULL;
  536. dbHandle handle;
  537. dbTable *Table;
  538. dbString dbstring;
  539. dbColumn *Column;
  540. char *valbuf;
  541. if (layer < 1) {
  542. G_warning(_("Cannot export attribute table fields for layer < 1. Skipping export"));
  543. return 1;
  544. }
  545. /* attempt to open attribute table for selected layer */
  546. db_init_string(&dbstring);
  547. Fi = Vect_get_field(Map, layer);
  548. if (Fi == NULL) {
  549. G_fatal_error(_("No attribute table found"));
  550. }
  551. Driver = db_start_driver(Fi->driver);
  552. if (Driver == NULL)
  553. G_fatal_error(_("Unable to start driver <%s>"), Fi->driver);
  554. db_init_handle(&handle);
  555. db_set_handle(&handle, Fi->database, NULL);
  556. if (db_open_database(Driver, &handle) != DB_OK)
  557. G_fatal_error(_("Unable to open database <%s> by driver <%s>"),
  558. Fi->database, Fi->driver);
  559. db_set_string(&dbstring, Fi->table);
  560. if (db_describe_table(Driver, &dbstring, &Table) != DB_OK)
  561. G_fatal_error(_("Unable to describe table <%s>"), Fi->table);
  562. /* analyse field structure */
  563. ncol = db_get_table_number_of_columns(Table);
  564. num_atts = 0;
  565. for (i = 0; i < ncol; i++) {
  566. Column = db_get_table_column(Table, i);
  567. colsqltype = db_get_column_sqltype(Column);
  568. colctype = db_sqltype_to_Ctype(colsqltype);
  569. if ((colctype == DB_C_TYPE_INT) || (colctype == DB_C_TYPE_DOUBLE)) {
  570. /* we don't want to export the category field twice */
  571. if (strcmp(db_get_column_name(Column), "cat")) {
  572. num_atts++;
  573. /* fprintf ( stderr, "%i: %s\n", num_atts, db_get_column_name(Column) ); */
  574. }
  575. }
  576. }
  577. if (num_atts < 1) {
  578. G_warning(_("No numerical attributes found. Skipping export"));
  579. db_close_database(Driver);
  580. db_shutdown_driver(Driver);
  581. return 1;
  582. }
  583. Cats = Vect_new_cats_struct();
  584. G_message("Writing %i scalar variables as cell data ...", num_atts);
  585. progress = 0;
  586. for (cur_att = 0; cur_att < ncol; cur_att++) {
  587. if (numcelldata > 0) {
  588. /*Write the pointdata */
  589. Column = db_get_table_column(Table, cur_att);
  590. colsqltype = db_get_column_sqltype(Column);
  591. colctype = db_sqltype_to_Ctype(colsqltype);
  592. if ((strcmp("cat", db_get_column_name(Column))) &&
  593. ((colctype == DB_C_TYPE_INT) ||
  594. (colctype == DB_C_TYPE_DOUBLE))) {
  595. if (colctype == DB_C_TYPE_INT) {
  596. /* G_message(" Writing integer scalar %s", db_get_column_name(Column) ); */
  597. fprintf(ascii, "SCALARS %s int 1\n",
  598. db_get_column_name(Column));
  599. }
  600. if (colctype == DB_C_TYPE_DOUBLE) {
  601. /* *G_message(" Writing double scalar %s", db_get_column_name(Column) ); */
  602. fprintf(ascii, "SCALARS %s double 1\n",
  603. db_get_column_name(Column));
  604. }
  605. fprintf(ascii, "LOOKUP_TABLE default\n");
  606. progress++;
  607. /*For every available vector type */
  608. for (k = 0; k < typenum; k++) {
  609. /*POINT KERNEL CENTROID */
  610. if (types[k] == GV_POINT || types[k] == GV_KERNEL ||
  611. types[k] == GV_CENTROID) {
  612. Vect_rewind(Map);
  613. while (1) {
  614. if (-1 ==
  615. (type =
  616. Vect_read_next_line(Map, NULL, Cats)))
  617. break;
  618. if (type == -2) /* EOF */
  619. break;
  620. if (type == types[k]) {
  621. Vect_cat_get(Cats, layer, &cat);
  622. valbuf =
  623. get_att((char *)
  624. db_get_column_name(Column), cat,
  625. Fi, Driver, ncol);
  626. if (valbuf == NULL) {
  627. db_close_database(Driver);
  628. db_shutdown_driver(Driver);
  629. G_fatal_error(_("Error reading value of attribute '%s'"),
  630. db_get_column_name(Column));
  631. }
  632. /* DEBUG
  633. fprintf ( stderr, "%s (%i) = %s\n", db_get_column_name(Column), cat, valbuf );
  634. */
  635. fprintf(ascii, " %s", valbuf);
  636. G_free(valbuf);
  637. }
  638. }
  639. }
  640. }
  641. for (k = 0; k < typenum; k++) {
  642. /*LINE BOUNDARY */
  643. if (types[k] == GV_LINE || types[k] == GV_BOUNDARY) {
  644. Vect_rewind(Map);
  645. while (1) {
  646. if (-1 ==
  647. (type =
  648. Vect_read_next_line(Map, NULL, Cats)))
  649. break;
  650. if (type == -2) /* EOF */
  651. break;
  652. if (type == types[k]) {
  653. Vect_cat_get(Cats, layer, &cat);
  654. valbuf =
  655. get_att((char *)
  656. db_get_column_name(Column), cat,
  657. Fi, Driver, ncol);
  658. if (valbuf == NULL) {
  659. db_close_database(Driver);
  660. db_shutdown_driver(Driver);
  661. G_fatal_error(_("Error reading value of attribute '%s'"),
  662. db_get_column_name(Column));
  663. }
  664. /* DEBUG
  665. fprintf ( stderr, "%s (%i) = %s\n", db_get_column_name(Column), cat, valbuf );
  666. */
  667. fprintf(ascii, " %s", valbuf);
  668. G_free(valbuf);
  669. }
  670. }
  671. }
  672. }
  673. for (k = 0; k < typenum; k++) {
  674. /*FACE */
  675. if (types[k] == GV_FACE) {
  676. Vect_rewind(Map);
  677. while (1) {
  678. if (-1 ==
  679. (type =
  680. Vect_read_next_line(Map, NULL, Cats)))
  681. break;
  682. if (type == -2) /* EOF */
  683. break;
  684. if (type == types[k]) {
  685. Vect_cat_get(Cats, layer, &cat);
  686. valbuf =
  687. get_att((char *)
  688. db_get_column_name(Column), cat,
  689. Fi, Driver, ncol);
  690. if (valbuf == NULL) {
  691. db_close_database(Driver);
  692. db_shutdown_driver(Driver);
  693. G_fatal_error(_("Error reading value of attribute '%s'"),
  694. db_get_column_name(Column));
  695. }
  696. /* DEBUG
  697. fprintf ( stderr, "%s (%i) = %s\n", db_get_column_name(Column), cat, valbuf );
  698. */
  699. fprintf(ascii, " %s", valbuf);
  700. G_free(valbuf);
  701. }
  702. }
  703. }
  704. }
  705. for (k = 0; k < typenum; k++) {
  706. /*AREA */
  707. if (types[k] == GV_AREA) {
  708. Vect_rewind(Map);
  709. for (i = 1;
  710. i <= info->typeinfo[types[k]]->numpolygons;
  711. i++) {
  712. centroid = Vect_get_area_centroid(Map, i);
  713. if (centroid > 0) {
  714. Vect_read_line(Map, NULL, Cats, centroid);
  715. }
  716. Vect_cat_get(Cats, layer, &cat);
  717. valbuf =
  718. get_att((char *)db_get_column_name(Column),
  719. cat, Fi, Driver, ncol);
  720. if (valbuf == NULL) {
  721. db_close_database(Driver);
  722. db_shutdown_driver(Driver);
  723. G_fatal_error(_("Error reading value of attribute '%s'"),
  724. db_get_column_name(Column));
  725. }
  726. /* DEBUG
  727. fprintf ( stderr, "%s (%i) = %s\n", db_get_column_name(Column), cat, valbuf );
  728. */
  729. fprintf(ascii, " %s", valbuf);
  730. G_free(valbuf);
  731. }
  732. }
  733. }
  734. fprintf(ascii, "\n");
  735. } /* END (do for all scalars != cat */
  736. }
  737. } /* END (step through all numerical attributes) */
  738. fprintf(stdout, "\n");
  739. fflush(stdout);
  740. db_close_database(Driver);
  741. db_shutdown_driver(Driver);
  742. return 1;
  743. }
  744. /* ************************************************************************* */
  745. /* This function writes attribute table fields as VTK labels **** */
  746. /* ************************************************************************* */
  747. int write_vtk_db_labels(FILE * ascii, struct Map_info *Map, VTKInfo * info,
  748. int layer, int *types, int typenum, int dp)
  749. {
  750. return 1;
  751. }
  752. /* ************************************************************************* */
  753. /* This function writes the point coordinates and the geometric feature **** */
  754. /* ************************************************************************* */
  755. int write_vtk(FILE * ascii, struct Map_info *Map, int layer, int *types,
  756. int typenum, int dp, double scale, int numatts, int labels)
  757. {
  758. VTKInfo *info;
  759. VTKTypeInfo **typeinfo;
  760. int i;
  761. int infonum =
  762. GV_POINT + GV_KERNEL + GV_CENTROID + GV_LINE + GV_BOUNDARY + GV_FACE +
  763. GV_AREA;
  764. /*Initiate the typeinfo structure for every supported type */
  765. typeinfo = (VTKTypeInfo **) calloc(infonum, sizeof(VTKTypeInfo *));
  766. for (i = 0; i < infonum; i++) {
  767. typeinfo[i] = (VTKTypeInfo *) calloc(1, sizeof(VTKTypeInfo));
  768. typeinfo[i]->numpoints = 0;
  769. typeinfo[i]->pointoffset = 0;
  770. typeinfo[i]->numvertices = 0;
  771. typeinfo[i]->verticesoffset = 0;
  772. typeinfo[i]->numlines = 0;
  773. typeinfo[i]->lineoffset = 0;
  774. typeinfo[i]->numpolygons = 0;
  775. typeinfo[i]->polygonoffset = 0;
  776. typeinfo[i]->generatedata = 1;
  777. }
  778. /*Initiate the info structure */
  779. info = (VTKInfo *) calloc(infonum, sizeof(VTKInfo));
  780. info->maxnumpoints = 0;
  781. info->maxnumvertices = 0;
  782. info->maxnumlines = 0;
  783. info->maxnumlinepoints = 0;
  784. info->maxnumpolygons = 0;
  785. info->maxnumpolygonpoints = 0;
  786. info->typeinfo = typeinfo;
  787. /*1. write the points */
  788. write_vtk_points(ascii, Map, info, types, typenum, dp, scale);
  789. /*2. write the cells */
  790. write_vtk_cells(ascii, Map, info, types, typenum);
  791. /*3. write the cat data */
  792. write_vtk_cat_data(ascii, Map, info, layer, types, typenum, dp);
  793. /*4. write the DB data: numerical attributes */
  794. if (numatts) {
  795. write_vtk_db_data(ascii, Map, info, layer, types, typenum, dp);
  796. }
  797. /*5. Write labels (not yet supported)
  798. if ( labels ) {
  799. write_vtk_db_labels(ascii, Map, info, layer, types, typenum, dp);
  800. }
  801. */
  802. /*Release the memory */
  803. for (i = 0; i < infonum; i++) {
  804. free(typeinfo[i]);
  805. }
  806. free(typeinfo);
  807. free(info);
  808. return 1;
  809. }
  810. /* ************************************************************************* */
  811. /* This function writes the point coordinates ****************************** */
  812. /* ************************************************************************* */
  813. void write_point_coordinates(struct line_pnts *Points, int dp, double scale,
  814. FILE * ascii)
  815. {
  816. char *xstring = NULL, *ystring = NULL, *zstring = NULL;
  817. double *xptr, *yptr, *zptr;
  818. xptr = Points->x;
  819. yptr = Points->y;
  820. zptr = Points->z;
  821. while (Points->n_points--) {
  822. G_asprintf(&xstring, "%.*f", dp, *xptr++ - x_extent);
  823. G_trim_decimal(xstring);
  824. G_asprintf(&ystring, "%.*f", dp, *yptr++ - y_extent);
  825. G_trim_decimal(ystring);
  826. G_asprintf(&zstring, "%.*f", dp, scale * (*zptr++));
  827. G_trim_decimal(zstring);
  828. fprintf(ascii, "%s %s %s \n", xstring, ystring, zstring);
  829. }
  830. return;
  831. }