plus.c 9.8 KB

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