read_nat.c 7.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343
  1. /*!
  2. \file read_nat.c
  3. \brief Vector library - reading data (native format)
  4. Higher level functions for reading/writing/manipulating vectors.
  5. The action of this routine can be modified by:
  6. - Vect_read_constraint_region()
  7. - Vect_read_constraint_type()
  8. - Vect_remove_constraints()
  9. (C) 2001-2008 by the GRASS Development Team
  10. This program is free software under the
  11. GNU General Public License (>=v2).
  12. Read the file COPYING that comes with GRASS
  13. for details.
  14. \author Original author CERL, probably Dave Gerdes or Mike Higgins.
  15. Update to GRASS 5.7 Radim Blazek and David D. Gray.
  16. \date 2001
  17. */
  18. #include <grass/gis.h>
  19. #include <grass/Vect.h>
  20. #include <grass/glocale.h>
  21. static int
  22. Vect__Read_line_nat(struct Map_info *,
  23. struct line_pnts *, struct line_cats *, long);
  24. /*!
  25. * \brief Read line from coor file on given offset.
  26. *
  27. * \param Map vector map
  28. * \param Points container used to store line points within
  29. * \param Cats container used to store line categories within
  30. * \param offset given offset
  31. *
  32. * \return line type
  33. * \return 0 dead line
  34. * \return -2 end of table (last row)
  35. * \return -1 out of memory
  36. */
  37. int
  38. V1_read_line_nat(struct Map_info *Map,
  39. struct line_pnts *Points,
  40. struct line_cats *Cats, long offset)
  41. {
  42. return Vect__Read_line_nat(Map, Points, Cats, offset);
  43. }
  44. /*!
  45. * \brief Read next line from coor file.
  46. *
  47. * \param Map vector map layer
  48. * \param line_p container used to store line points within
  49. * \param line_c container used to store line categories within
  50. *
  51. * \return line type
  52. * \return 0 dead line
  53. * \return -2 end of table (last row)
  54. * \return -1 out of memory
  55. */
  56. int
  57. V1_read_next_line_nat(struct Map_info *Map,
  58. struct line_pnts *line_p, struct line_cats *line_c)
  59. {
  60. int itype;
  61. long offset;
  62. BOUND_BOX lbox, mbox;
  63. G_debug(3, "V1_read_next_line_nat()");
  64. if (Map->Constraint_region_flag)
  65. Vect_get_constraint_box(Map, &mbox);
  66. while (1) {
  67. offset = dig_ftell(&(Map->dig_fp));
  68. itype = Vect__Read_line_nat(Map, line_p, line_c, offset);
  69. if (itype < 0)
  70. return (itype);
  71. if (itype == 0) /* is it DEAD? */
  72. continue;
  73. /* Constraint on Type of line
  74. * Default is all of Point, Line, Area and whatever else comes along
  75. */
  76. if (Map->Constraint_type_flag) {
  77. if (!(itype & Map->Constraint_type))
  78. continue;
  79. }
  80. /* Constraint on specified region */
  81. if (Map->Constraint_region_flag) {
  82. Vect_line_box(line_p, &lbox);
  83. if (!Vect_box_overlap(&lbox, &mbox))
  84. continue;
  85. }
  86. return (itype);
  87. }
  88. /* NOTREACHED */
  89. }
  90. /*!
  91. * \brief Reads any specified line, this is NOT affected by constraints
  92. *
  93. * \param Map vector map layer
  94. * \param line_p container used to store line points within
  95. * \param line_c container used to store line categories within
  96. * \param line line id
  97. *
  98. * \return line type ( > 0 )
  99. * \return 0 dead line
  100. * \return -1 out of memory
  101. * \return -2 end of file
  102. */
  103. int
  104. V2_read_line_nat(struct Map_info *Map,
  105. struct line_pnts *line_p, struct line_cats *line_c, int line)
  106. {
  107. P_LINE *Line;
  108. G_debug(3, "V2_read_line_nat(): line = %d", line);
  109. Line = Map->plus.Line[line];
  110. if (Line == NULL)
  111. G_fatal_error("V2_read_line_nat(): %s %d",
  112. _("Attempt to read dead line"), line);
  113. return Vect__Read_line_nat(Map, line_p, line_c, Line->offset);
  114. }
  115. /*!
  116. * \brief Reads next unread line each time called. Use Vect_rewind to reset.
  117. *
  118. * \param Map vector map layer
  119. * \param line_p container used to store line points within
  120. * \param line_c container used to store line categories within
  121. *
  122. * \return line type ( > 0 )
  123. * \return 0 dead line
  124. * \return -1 out of memory
  125. * \return -2 end of file
  126. */
  127. int
  128. V2_read_next_line_nat(struct Map_info *Map,
  129. struct line_pnts *line_p, struct line_cats *line_c)
  130. {
  131. register int line;
  132. register P_LINE *Line;
  133. BOUND_BOX lbox, mbox;
  134. G_debug(3, "V2_read_next_line_nat()");
  135. if (Map->Constraint_region_flag)
  136. Vect_get_constraint_box(Map, &mbox);
  137. while (1) {
  138. line = Map->next_line;
  139. if (line > Map->plus.n_lines)
  140. return (-2);
  141. Line = Map->plus.Line[line];
  142. if (Line == NULL) { /* Dead line */
  143. Map->next_line++;
  144. continue;
  145. }
  146. if ((Map->Constraint_type_flag &&
  147. !(Line->type & Map->Constraint_type))) {
  148. Map->next_line++;
  149. continue;
  150. }
  151. if (Map->Constraint_region_flag) {
  152. Vect_get_line_box(Map, line, &lbox);
  153. if (!Vect_box_overlap(&lbox, &mbox)) {
  154. Map->next_line++;
  155. continue;
  156. }
  157. }
  158. return V2_read_line_nat(Map, line_p, line_c, Map->next_line++);
  159. }
  160. /* NOTREACHED */ }
  161. /*!
  162. * \brief Read line from coor file
  163. *
  164. * \param Map vector map layer
  165. * \param p container used to store line points within
  166. * \param c container used to store line categories within
  167. * \param offset given offset
  168. *
  169. * \return line type ( > 0 )
  170. * \return 0 dead line
  171. * \return -1 out of memory
  172. * \return -2 end of file
  173. */
  174. int
  175. Vect__Read_line_nat(struct Map_info *Map,
  176. struct line_pnts *p, struct line_cats *c, long offset)
  177. {
  178. int i, dead = 0;
  179. int n_points;
  180. long size;
  181. int n_cats, do_cats;
  182. int type;
  183. char rhead, nc;
  184. short field;
  185. G_debug(3, "Vect__Read_line_nat: offset = %ld", offset);
  186. Map->head.last_offset = offset;
  187. /* reads must set in_head, but writes use default */
  188. dig_set_cur_port(&(Map->head.port));
  189. dig_fseek(&(Map->dig_fp), offset, 0);
  190. if (0 >= dig__fread_port_C(&rhead, 1, &(Map->dig_fp)))
  191. return (-2);
  192. if (!(rhead & 0x01)) /* dead line */
  193. dead = 1;
  194. if (rhead & 0x02) /* categories exists */
  195. do_cats = 1; /* do not return here let file offset moves forward to next */
  196. else /* line */
  197. do_cats = 0;
  198. rhead >>= 2;
  199. type = dig_type_from_store((int)rhead);
  200. G_debug(3, " type = %d, do_cats = %d dead = %d", type, do_cats, dead);
  201. if (c != NULL)
  202. c->n_cats = 0;
  203. if (do_cats) {
  204. if (Map->head.Version_Minor == 1) { /* coor format 5.1 */
  205. if (0 >= dig__fread_port_I(&n_cats, 1, &(Map->dig_fp)))
  206. return (-2);
  207. }
  208. else { /* coor format 5.0 */
  209. if (0 >= dig__fread_port_C(&nc, 1, &(Map->dig_fp)))
  210. return (-2);
  211. n_cats = (int)nc;
  212. }
  213. G_debug(3, " n_cats = %d", n_cats);
  214. if (c != NULL) {
  215. c->n_cats = n_cats;
  216. if (n_cats > 0) {
  217. if (0 > dig_alloc_cats(c, (int)n_cats + 1))
  218. return (-1);
  219. if (Map->head.Version_Minor == 1) { /* coor format 5.1 */
  220. if (0 >=
  221. dig__fread_port_I(c->field, n_cats, &(Map->dig_fp)))
  222. return (-2);
  223. }
  224. else { /* coor format 5.0 */
  225. for (i = 0; i < n_cats; i++) {
  226. if (0 >= dig__fread_port_S(&field, 1, &(Map->dig_fp)))
  227. return (-2);
  228. c->field[i] = (int)field;
  229. }
  230. }
  231. if (0 >= dig__fread_port_I(c->cat, n_cats, &(Map->dig_fp)))
  232. return (-2);
  233. }
  234. }
  235. else {
  236. if (Map->head.Version_Minor == 1) { /* coor format 5.1 */
  237. size = (2 * PORT_INT) * n_cats;
  238. }
  239. else { /* coor format 5.0 */
  240. size = (PORT_SHORT + PORT_INT) * n_cats;
  241. }
  242. dig_fseek(&(Map->dig_fp), size, SEEK_CUR);
  243. }
  244. }
  245. if (type & GV_POINTS) {
  246. n_points = 1;
  247. }
  248. else {
  249. if (0 >= dig__fread_port_I(&n_points, 1, &(Map->dig_fp)))
  250. return (-2);
  251. }
  252. G_debug(3, " n_points = %d", n_points);
  253. if (p != NULL) {
  254. if (0 > dig_alloc_points(p, n_points + 1))
  255. return (-1);
  256. p->n_points = n_points;
  257. if (0 >= dig__fread_port_D(p->x, n_points, &(Map->dig_fp)))
  258. return (-2);
  259. if (0 >= dig__fread_port_D(p->y, n_points, &(Map->dig_fp)))
  260. return (-2);
  261. if (Map->head.with_z) {
  262. if (0 >= dig__fread_port_D(p->z, n_points, &(Map->dig_fp)))
  263. return (-2);
  264. }
  265. else {
  266. for (i = 0; i < n_points; i++)
  267. p->z[i] = 0.0;
  268. }
  269. }
  270. else {
  271. if (Map->head.with_z)
  272. size = n_points * 3 * PORT_DOUBLE;
  273. else
  274. size = n_points * 2 * PORT_DOUBLE;
  275. dig_fseek(&(Map->dig_fp), size, SEEK_CUR);
  276. }
  277. G_debug(3, " off = %ld", dig_ftell(&(Map->dig_fp)));
  278. if (dead)
  279. return 0;
  280. return (type);
  281. }