plus.c 9.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468
  1. /**
  2. * \file plus.c
  3. *
  4. * \brief Vector library - update topo structure (lower level functions)
  5. *
  6. * Lower level functions for reading/writing/manipulating vectors.
  7. *
  8. * This program is free software under the GNU General Public License
  9. * (>=v2). Read the file COPYING that comes with GRASS for details.
  10. *
  11. * \author CERL (probably Dave Gerdes), Radim Blazek
  12. *
  13. * \date 2001-2006
  14. */
  15. #include <grass/config.h>
  16. #include <sys/types.h>
  17. #include <unistd.h>
  18. #include <stdlib.h>
  19. #include <stdio.h>
  20. #include <grass/gis.h>
  21. #include <grass/vector.h>
  22. #include <grass/glocale.h>
  23. /*!
  24. * \brief Init head structure
  25. *
  26. * \param[in,out] Plus pointer to Plus_head structure
  27. *
  28. * \return 1
  29. */
  30. int dig_init_plus(struct Plus_head *Plus)
  31. {
  32. G_debug(3, "dig_init_plus()");
  33. Plus->Version_Major = 0;
  34. Plus->Version_Minor = 0;
  35. Plus->Back_Major = 0;
  36. Plus->Back_Minor = 0;
  37. Plus->with_z = 0;
  38. Plus->off_t_size = 0;
  39. Plus->box.N = 0;
  40. Plus->box.S = 0;
  41. Plus->box.E = 0;
  42. Plus->box.W = 0;
  43. Plus->box.T = 0;
  44. Plus->box.B = 0;
  45. Plus->built = GV_BUILD_NONE;
  46. Plus->Node = NULL;
  47. Plus->Line = NULL;
  48. Plus->Area = NULL;
  49. Plus->Isle = NULL;
  50. Plus->n_nodes = 0;
  51. Plus->n_edges = 0;
  52. Plus->n_lines = 0;
  53. Plus->n_areas = 0;
  54. Plus->n_isles = 0;
  55. Plus->n_volumes = 0;
  56. Plus->n_holes = 0;
  57. Plus->alloc_nodes = 0;
  58. Plus->alloc_edges = 0;
  59. Plus->alloc_lines = 0;
  60. Plus->alloc_areas = 0;
  61. Plus->alloc_isles = 0;
  62. Plus->alloc_volumes = 0;
  63. Plus->alloc_holes = 0;
  64. Plus->n_plines = 0;
  65. Plus->n_llines = 0;
  66. Plus->n_blines = 0;
  67. Plus->n_clines = 0;
  68. Plus->n_flines = 0;
  69. Plus->n_klines = 0;
  70. Plus->Node_offset = 0L;
  71. Plus->Edge_offset = 0L;
  72. Plus->Line_offset = 0L;
  73. Plus->Area_offset = 0L;
  74. Plus->Isle_offset = 0L;
  75. Plus->Volume_offset = 0L;
  76. Plus->Hole_offset = 0L;
  77. Plus->Node_spidx_offset = 0L;
  78. Plus->Edge_spidx_offset = 0L;
  79. Plus->Line_spidx_offset = 0L;
  80. Plus->Area_spidx_offset = 0L;
  81. Plus->Isle_spidx_offset = 0L;
  82. Plus->Volume_spidx_offset = 0L;
  83. Plus->Hole_spidx_offset = 0L;
  84. dig_spidx_init(Plus);
  85. dig_cidx_init(Plus);
  86. return 1;
  87. }
  88. /*!
  89. * \brief Free Plus->Node structure
  90. *
  91. * \param[in] Plus pointer to Plus_head structure
  92. */
  93. void dig_free_plus_nodes(struct Plus_head *Plus)
  94. {
  95. int i;
  96. P_NODE *Node;
  97. G_debug(2, "dig_free_plus_nodes()");
  98. /* Nodes */
  99. if (Plus->Node) { /* it may be that header only is loaded */
  100. for (i = 1; i <= Plus->n_nodes; i++) {
  101. Node = Plus->Node[i];
  102. if (Node == NULL)
  103. continue;
  104. dig_free_node(Node);
  105. }
  106. G_free(Plus->Node);
  107. }
  108. Plus->Node = NULL;
  109. Plus->n_nodes = 0;
  110. Plus->alloc_nodes = 0;
  111. }
  112. /*!
  113. * \brief Free Plus->Line structure
  114. *
  115. * \param[in] Plus pointer to Plus_head structure
  116. */
  117. void dig_free_plus_lines(struct Plus_head *Plus)
  118. {
  119. int i;
  120. P_LINE *Line;
  121. G_debug(2, "dig_free_plus_lines()");
  122. /* Lines */
  123. if (Plus->Line) { /* it may be that header only is loaded */
  124. for (i = 1; i <= Plus->n_lines; i++) {
  125. Line = Plus->Line[i];
  126. if (Line == NULL)
  127. continue;
  128. dig_free_line(Line);
  129. }
  130. G_free(Plus->Line);
  131. }
  132. Plus->Line = NULL;
  133. Plus->n_lines = 0;
  134. Plus->alloc_lines = 0;
  135. Plus->n_plines = 0;
  136. Plus->n_llines = 0;
  137. Plus->n_blines = 0;
  138. Plus->n_clines = 0;
  139. Plus->n_flines = 0;
  140. Plus->n_klines = 0;
  141. }
  142. /*!
  143. * \brief Free Plus->Area structure
  144. *
  145. * \param[in] Plus pointer to Plus_head structure
  146. */
  147. void dig_free_plus_areas(struct Plus_head *Plus)
  148. {
  149. int i;
  150. P_AREA *Area;
  151. G_debug(2, "dig_free_plus_areas()");
  152. /* Areas */
  153. if (Plus->Area) { /* it may be that header only is loaded */
  154. for (i = 1; i <= Plus->n_areas; i++) {
  155. Area = Plus->Area[i];
  156. if (Area == NULL)
  157. continue;
  158. dig_free_area(Area);
  159. }
  160. G_free(Plus->Area);
  161. }
  162. Plus->Area = NULL;
  163. Plus->n_areas = 0;
  164. Plus->alloc_areas = 0;
  165. }
  166. /*!
  167. * \brief Free Plus->Isle structure
  168. *
  169. * \param[in] Plus pointer to Plus_head structure
  170. */
  171. void dig_free_plus_isles(struct Plus_head *Plus)
  172. {
  173. int i;
  174. P_ISLE *Isle;
  175. G_debug(2, "dig_free_plus_isles()");
  176. /* Isles */
  177. if (Plus->Isle) { /* it may be that header only is loaded */
  178. for (i = 1; i <= Plus->n_isles; i++) {
  179. Isle = Plus->Isle[i];
  180. if (Isle == NULL)
  181. continue;
  182. dig_free_isle(Isle);
  183. }
  184. G_free(Plus->Isle);
  185. }
  186. Plus->Isle = NULL;
  187. Plus->n_isles = 0;
  188. Plus->alloc_isles = 0;
  189. }
  190. /*!
  191. * \brief Free Plus structure.
  192. *
  193. * Structure is not inited and dig_init_plus() should follow.
  194. *
  195. * \param[in] Plus pointer to Plus_head structure
  196. */
  197. void dig_free_plus(struct Plus_head *Plus)
  198. {
  199. G_debug(2, "dig_free_plus()");
  200. dig_free_plus_nodes(Plus);
  201. dig_free_plus_lines(Plus);
  202. dig_free_plus_areas(Plus);
  203. dig_free_plus_isles(Plus);
  204. dig_cidx_free(Plus);
  205. }
  206. /*!
  207. * \brief Reads topo file to topo structure.
  208. *
  209. * \param[in,out] Plus pointer to Plus_head structure
  210. * \param[in] plus topo file
  211. * \param[in] head_only read only head
  212. *
  213. * \return 1 on success
  214. * \return 0 on error
  215. */
  216. int dig_load_plus(struct Plus_head *Plus, GVFILE * plus, int head_only)
  217. {
  218. int i;
  219. G_debug(1, "dig_load_plus()");
  220. /* TODO
  221. if (do_checks)
  222. dig_do_file_checks (map, map->plus_file, map->digit_file);
  223. */
  224. /* free and init old */
  225. dig_init_plus(Plus);
  226. /* Now let's begin reading the Plus file nodes, lines, areas and isles */
  227. if (dig_Rd_Plus_head(plus, Plus) == -1)
  228. return 0;
  229. if (head_only)
  230. return 1;
  231. dig_set_cur_port(&(Plus->port));
  232. /* Nodes */
  233. if (dig_fseek(plus, Plus->Node_offset, 0) == -1)
  234. G_fatal_error(_("Unable read topology for nodes"));
  235. dig_alloc_nodes(Plus, Plus->n_nodes);
  236. for (i = 1; i <= Plus->n_nodes; i++) {
  237. if (dig_Rd_P_node(Plus, i, plus) == -1)
  238. G_fatal_error(_("Unable to read topology for node %d"), i);
  239. }
  240. /* Lines */
  241. if (dig_fseek(plus, Plus->Line_offset, 0) == -1)
  242. G_fatal_error(_("Unable read topology for lines"));
  243. dig_alloc_lines(Plus, Plus->n_lines);
  244. for (i = 1; i <= Plus->n_lines; i++) {
  245. if (dig_Rd_P_line(Plus, i, plus) == -1)
  246. G_fatal_error(_("Unable to read topology for line %d"), i);
  247. }
  248. /* Areas */
  249. if (dig_fseek(plus, Plus->Area_offset, 0) == -1)
  250. G_fatal_error(_("Unable to read topo for areas"));
  251. dig_alloc_areas(Plus, Plus->n_areas);
  252. for (i = 1; i <= Plus->n_areas; i++) {
  253. if (dig_Rd_P_area(Plus, i, plus) == -1)
  254. G_fatal_error(_("Unable read topology for area %d"), i);
  255. }
  256. /* Isles */
  257. if (dig_fseek(plus, Plus->Isle_offset, 0) == -1)
  258. G_fatal_error(_("Unable to read topology for isles"));
  259. dig_alloc_isles(Plus, Plus->n_isles);
  260. for (i = 1; i <= Plus->n_isles; i++) {
  261. if (dig_Rd_P_isle(Plus, i, plus) == -1)
  262. G_fatal_error(_("Unable to read topology for isle %d"), i);
  263. }
  264. return (1);
  265. }
  266. /*!
  267. * \brief Writes topo structure to topo file
  268. *
  269. * \param[in,out] fp_plus topo file
  270. * \param[in] Plus pointer to Plus_head structure
  271. *
  272. * \return 0 on success
  273. * \return -1 on error
  274. */
  275. int dig_write_plus_file(GVFILE * fp_plus, struct Plus_head *Plus)
  276. {
  277. dig_set_cur_port(&(Plus->port));
  278. dig_rewind(fp_plus);
  279. if (dig_Wr_Plus_head(fp_plus, Plus) < 0) {
  280. G_warning(_("Unable to write head to plus file"));
  281. return (-1);
  282. }
  283. if (dig_write_nodes(fp_plus, Plus) < 0) {
  284. G_warning(_("Unable to write nodes to plus file"));
  285. return (-1);
  286. }
  287. if (dig_write_lines(fp_plus, Plus) < 0) {
  288. G_warning(_("Unable to write lines to plus file"));
  289. return (-1);
  290. }
  291. if (dig_write_areas(fp_plus, Plus) < 0) {
  292. G_warning(_("Unable to write areas to plus file"));
  293. return (-1);
  294. }
  295. if (dig_write_isles(fp_plus, Plus) < 0) {
  296. G_warning(_("Unable to write isles to plus file"));
  297. return (-1);
  298. }
  299. dig_rewind(fp_plus);
  300. if (dig_Wr_Plus_head(fp_plus, Plus) < 0) {
  301. G_warning(_("Unable to write head to plus file"));
  302. return (-1);
  303. }
  304. dig_fflush(fp_plus);
  305. return (0);
  306. } /* write_plus_file() */
  307. /*!
  308. * \brief Writes topo structure (nodes) to topo file
  309. *
  310. * \param[in,out] fp_plus topo file
  311. * \param[in] Plus pointer to Plus_head structure
  312. *
  313. * \return 0 on success
  314. * \return -1 on error
  315. */
  316. int dig_write_nodes(GVFILE * plus, struct Plus_head *Plus)
  317. {
  318. int i;
  319. Plus->Node_offset = dig_ftell(plus);
  320. for (i = 1; i <= Plus->n_nodes; i++) {
  321. if (dig_Wr_P_node(Plus, i, plus) < 0)
  322. return (-1);
  323. }
  324. return (0);
  325. } /* write_nodes() */
  326. /*!
  327. * \brief Writes topo structure (lines) to topo file
  328. *
  329. * \param[in,out] fp_plus topo file
  330. * \param[in] Plus pointer to Plus_head structure
  331. *
  332. * \return 0 on success
  333. * \return -1 on error
  334. */
  335. int dig_write_lines(GVFILE * plus, struct Plus_head *Plus)
  336. {
  337. int i;
  338. Plus->Line_offset = dig_ftell(plus);
  339. for (i = 1; i <= Plus->n_lines; i++) {
  340. if (dig_Wr_P_line(Plus, i, plus) < 0)
  341. return (-1);
  342. }
  343. return (0);
  344. } /* write_line() */
  345. /*!
  346. * \brief Writes topo structure (areas) to topo file
  347. *
  348. * \param[in,out] fp_plus topo file
  349. * \param[in] Plus pointer to Plus_head structure
  350. *
  351. * \return 0 on success
  352. * \return -1 on error
  353. */
  354. int dig_write_areas(GVFILE * plus, struct Plus_head *Plus)
  355. {
  356. int i;
  357. Plus->Area_offset = dig_ftell(plus);
  358. for (i = 1; i <= Plus->n_areas; i++) {
  359. if (dig_Wr_P_area(Plus, i, plus) < 0)
  360. return (-1);
  361. }
  362. return (0);
  363. } /* write_areas() */
  364. /*!
  365. * \brief Writes topo structure (isles) to topo file
  366. *
  367. * \param[in,out] fp_plus topo file
  368. * \param[in] Plus pointer to Plus_head structure
  369. *
  370. * \return 0 on success
  371. * \return -1 on error
  372. */
  373. int dig_write_isles(GVFILE * plus, struct Plus_head *Plus)
  374. {
  375. int i;
  376. Plus->Isle_offset = dig_ftell(plus);
  377. for (i = 1; i <= Plus->n_isles; i++) {
  378. if (dig_Wr_P_isle(Plus, i, plus) < 0)
  379. return (-1);
  380. }
  381. return (0);
  382. } /* write_isles() */