read_nat.c 7.9 KB

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