plus.c 8.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411
  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 <sys/types.h>
  16. #include <unistd.h>
  17. #include <stdlib.h>
  18. #include <stdio.h>
  19. #include <grass/vector.h>
  20. #include <grass/glocale.h>
  21. /*!
  22. * \brief Initialize Plus_head structure
  23. *
  24. * \param[in,out] Plus pointer to Plus_head structure
  25. *
  26. * \return 1
  27. */
  28. int dig_init_plus(struct Plus_head *Plus)
  29. {
  30. G_debug(3, "dig_init_plus()");
  31. G_zero(Plus, sizeof(struct Plus_head));
  32. Plus->built = GV_BUILD_NONE;
  33. dig_spidx_init(Plus);
  34. dig_cidx_init(Plus);
  35. return 1;
  36. }
  37. /*!
  38. * \brief Free Plus->Node structure
  39. *
  40. * \param[in] Plus pointer to Plus_head structure
  41. */
  42. void dig_free_plus_nodes(struct Plus_head *Plus)
  43. {
  44. int i;
  45. struct P_node *Node;
  46. G_debug(2, "dig_free_plus_nodes()");
  47. /* Nodes */
  48. if (Plus->Node) { /* it may be that header only is loaded */
  49. for (i = 1; i <= Plus->n_nodes; i++) {
  50. Node = Plus->Node[i];
  51. if (Node == NULL)
  52. continue;
  53. dig_free_node(Node);
  54. }
  55. G_free(Plus->Node);
  56. }
  57. Plus->Node = NULL;
  58. Plus->n_nodes = 0;
  59. Plus->alloc_nodes = 0;
  60. }
  61. /*!
  62. * \brief Free Plus->Line structure
  63. *
  64. * \param[in] Plus pointer to Plus_head structure
  65. */
  66. void dig_free_plus_lines(struct Plus_head *Plus)
  67. {
  68. int i;
  69. struct P_line *Line;
  70. G_debug(2, "dig_free_plus_lines()");
  71. /* Lines */
  72. if (Plus->Line) { /* it may be that header only is loaded */
  73. for (i = 1; i <= Plus->n_lines; i++) {
  74. Line = Plus->Line[i];
  75. if (Line == NULL)
  76. continue;
  77. dig_free_line(Line);
  78. }
  79. G_free(Plus->Line);
  80. }
  81. Plus->Line = NULL;
  82. Plus->n_lines = 0;
  83. Plus->alloc_lines = 0;
  84. Plus->n_plines = 0;
  85. Plus->n_llines = 0;
  86. Plus->n_blines = 0;
  87. Plus->n_clines = 0;
  88. Plus->n_flines = 0;
  89. Plus->n_klines = 0;
  90. }
  91. /*!
  92. * \brief Free Plus->Area structure
  93. *
  94. * \param[in] Plus pointer to Plus_head structure
  95. */
  96. void dig_free_plus_areas(struct Plus_head *Plus)
  97. {
  98. int i;
  99. struct P_area *Area;
  100. G_debug(2, "dig_free_plus_areas()");
  101. /* Areas */
  102. if (Plus->Area) { /* it may be that header only is loaded */
  103. for (i = 1; i <= Plus->n_areas; i++) {
  104. Area = Plus->Area[i];
  105. if (Area == NULL)
  106. continue;
  107. dig_free_area(Area);
  108. }
  109. G_free(Plus->Area);
  110. }
  111. Plus->Area = NULL;
  112. Plus->n_areas = 0;
  113. Plus->alloc_areas = 0;
  114. }
  115. /*!
  116. * \brief Free Plus->Isle structure
  117. *
  118. * \param[in] Plus pointer to Plus_head structure
  119. */
  120. void dig_free_plus_isles(struct Plus_head *Plus)
  121. {
  122. int i;
  123. struct P_isle *Isle;
  124. G_debug(2, "dig_free_plus_isles()");
  125. /* Isles */
  126. if (Plus->Isle) { /* it may be that header only is loaded */
  127. for (i = 1; i <= Plus->n_isles; i++) {
  128. Isle = Plus->Isle[i];
  129. if (Isle == NULL)
  130. continue;
  131. dig_free_isle(Isle);
  132. }
  133. G_free(Plus->Isle);
  134. }
  135. Plus->Isle = NULL;
  136. Plus->n_isles = 0;
  137. Plus->alloc_isles = 0;
  138. }
  139. /*!
  140. * \brief Free Plus structure.
  141. *
  142. * Structure is not inited and dig_init_plus() should follow.
  143. *
  144. * \param[in] Plus pointer to Plus_head structure
  145. */
  146. void dig_free_plus(struct Plus_head *Plus)
  147. {
  148. G_debug(2, "dig_free_plus()");
  149. dig_free_plus_nodes(Plus);
  150. dig_free_plus_lines(Plus);
  151. dig_free_plus_areas(Plus);
  152. dig_free_plus_isles(Plus);
  153. dig_spidx_free(Plus);
  154. dig_cidx_free(Plus);
  155. }
  156. /*!
  157. * \brief Reads topo file to topo structure.
  158. *
  159. * \param[in,out] Plus pointer to Plus_head structure
  160. * \param[in] plus topo file
  161. * \param[in] head_only read only head
  162. *
  163. * \return 1 on success
  164. * \return 0 on error
  165. */
  166. int dig_load_plus(struct Plus_head *Plus, struct gvfile * plus, int head_only)
  167. {
  168. int i;
  169. G_debug(1, "dig_load_plus()");
  170. /* TODO
  171. if (do_checks)
  172. dig_do_file_checks (map, map->plus_file, map->digit_file);
  173. */
  174. /* free and init old */
  175. dig_free_plus(Plus);
  176. dig_init_plus(Plus);
  177. /* Now let's begin reading the Plus file nodes, lines, areas and isles */
  178. if (dig_Rd_Plus_head(plus, Plus) == -1)
  179. return 0;
  180. if (head_only)
  181. return 1;
  182. dig_set_cur_port(&(Plus->port));
  183. /* Nodes */
  184. if (dig_fseek(plus, Plus->Node_offset, 0) == -1)
  185. G_fatal_error(_("Unable read topology for nodes"));
  186. dig_alloc_nodes(Plus, Plus->n_nodes);
  187. for (i = 1; i <= Plus->n_nodes; i++) {
  188. if (dig_Rd_P_node(Plus, i, plus) == -1)
  189. G_fatal_error(_("Unable to read topology for node %d"), i);
  190. }
  191. /* Lines */
  192. if (dig_fseek(plus, Plus->Line_offset, 0) == -1)
  193. G_fatal_error(_("Unable read topology for lines"));
  194. dig_alloc_lines(Plus, Plus->n_lines);
  195. for (i = 1; i <= Plus->n_lines; i++) {
  196. if (dig_Rd_P_line(Plus, i, plus) == -1)
  197. G_fatal_error(_("Unable to read topology for line %d"), i);
  198. }
  199. /* Areas */
  200. if (dig_fseek(plus, Plus->Area_offset, 0) == -1)
  201. G_fatal_error(_("Unable to read topo for areas"));
  202. dig_alloc_areas(Plus, Plus->n_areas);
  203. for (i = 1; i <= Plus->n_areas; i++) {
  204. if (dig_Rd_P_area(Plus, i, plus) == -1)
  205. G_fatal_error(_("Unable read topology for area %d"), i);
  206. }
  207. /* Isles */
  208. if (dig_fseek(plus, Plus->Isle_offset, 0) == -1)
  209. G_fatal_error(_("Unable to read topology for isles"));
  210. dig_alloc_isles(Plus, Plus->n_isles);
  211. for (i = 1; i <= Plus->n_isles; i++) {
  212. if (dig_Rd_P_isle(Plus, i, plus) == -1)
  213. G_fatal_error(_("Unable to read topology for isle %d"), i);
  214. }
  215. return (1);
  216. }
  217. /*!
  218. * \brief Writes topo structure to topo file
  219. *
  220. * \param[in,out] fp_plus topo file
  221. * \param[in] Plus pointer to Plus_head structure
  222. *
  223. * \return 0 on success
  224. * \return -1 on error
  225. */
  226. int dig_write_plus_file(struct gvfile * fp_plus, struct Plus_head *Plus)
  227. {
  228. dig_set_cur_port(&(Plus->port));
  229. dig_rewind(fp_plus);
  230. if (dig_Wr_Plus_head(fp_plus, Plus) < 0) {
  231. G_warning(_("Unable to write head to plus file"));
  232. return (-1);
  233. }
  234. if (dig_write_nodes(fp_plus, Plus) < 0) {
  235. G_warning(_("Unable to write nodes to plus file"));
  236. return (-1);
  237. }
  238. if (dig_write_lines(fp_plus, Plus) < 0) {
  239. G_warning(_("Unable to write lines to plus file"));
  240. return (-1);
  241. }
  242. if (dig_write_areas(fp_plus, Plus) < 0) {
  243. G_warning(_("Unable to write areas to plus file"));
  244. return (-1);
  245. }
  246. if (dig_write_isles(fp_plus, Plus) < 0) {
  247. G_warning(_("Unable to write isles to plus file"));
  248. return (-1);
  249. }
  250. dig_rewind(fp_plus);
  251. if (dig_Wr_Plus_head(fp_plus, Plus) < 0) {
  252. G_warning(_("Unable to write head to plus file"));
  253. return (-1);
  254. }
  255. dig_fflush(fp_plus);
  256. return (0);
  257. } /* write_plus_file() */
  258. /*!
  259. * \brief Writes topo structure (nodes) to topo file
  260. *
  261. * \param[in,out] plus topo file
  262. * \param[in] Plus pointer to Plus_head structure
  263. *
  264. * \return 0 on success
  265. * \return -1 on error
  266. */
  267. int dig_write_nodes(struct gvfile * plus, struct Plus_head *Plus)
  268. {
  269. int i;
  270. Plus->Node_offset = dig_ftell(plus);
  271. for (i = 1; i <= Plus->n_nodes; i++) {
  272. if (dig_Wr_P_node(Plus, i, plus) < 0)
  273. return (-1);
  274. }
  275. return (0);
  276. } /* write_nodes() */
  277. /*!
  278. * \brief Writes topo structure (lines) to topo file
  279. *
  280. * \param[in,out] plus topo file
  281. * \param[in] Plus pointer to Plus_head structure
  282. *
  283. * \return 0 on success
  284. * \return -1 on error
  285. */
  286. int dig_write_lines(struct gvfile * plus, struct Plus_head *Plus)
  287. {
  288. int i;
  289. Plus->Line_offset = dig_ftell(plus);
  290. for (i = 1; i <= Plus->n_lines; i++) {
  291. if (dig_Wr_P_line(Plus, i, plus) < 0)
  292. return (-1);
  293. }
  294. return (0);
  295. } /* write_line() */
  296. /*!
  297. * \brief Writes topo structure (areas) to topo file
  298. *
  299. * \param[in,out] plus topo file
  300. * \param[in] Plus pointer to Plus_head structure
  301. *
  302. * \return 0 on success
  303. * \return -1 on error
  304. */
  305. int dig_write_areas(struct gvfile * plus, struct Plus_head *Plus)
  306. {
  307. int i;
  308. Plus->Area_offset = dig_ftell(plus);
  309. for (i = 1; i <= Plus->n_areas; i++) {
  310. if (dig_Wr_P_area(Plus, i, plus) < 0)
  311. return (-1);
  312. }
  313. return (0);
  314. } /* write_areas() */
  315. /*!
  316. * \brief Writes topo structure (isles) to topo file
  317. *
  318. * \param[in,out] plus topo file
  319. * \param[in] Plus pointer to Plus_head structure
  320. *
  321. * \return 0 on success
  322. * \return -1 on error
  323. */
  324. int dig_write_isles(struct gvfile * plus, struct Plus_head *Plus)
  325. {
  326. int i;
  327. Plus->Isle_offset = dig_ftell(plus);
  328. for (i = 1; i <= Plus->n_isles; i++) {
  329. if (dig_Wr_P_isle(Plus, i, plus) < 0)
  330. return (-1);
  331. }
  332. return (0);
  333. } /* write_isles() */