write.c 8.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339
  1. /*!
  2. \file lib/vector/Vlib/write.c
  3. \brief Vector library - write vector features
  4. Higher level functions for reading/writing/manipulating vectors.
  5. Operations:
  6. - Write new feature
  7. - Rewrite feature
  8. - Delete feature
  9. - Restore deleted feature
  10. (C) 2001-2010, 2012 by the GRASS Development Team
  11. This program is free software under the GNU General Public License
  12. (>=v2). Read the file COPYING that comes with GRASS for details.
  13. \author Radim Blazek
  14. \author Updated by Martin Landa <landa.martin gmail.com>
  15. (restore lines, OGR & PostGIS support)
  16. */
  17. #include <sys/types.h>
  18. #include <grass/glocale.h>
  19. #include <grass/vector.h>
  20. static off_t write_dummy()
  21. {
  22. G_warning("Vect_write_line() %s",
  23. _("for this format/level not supported"));
  24. return -1;
  25. }
  26. static off_t rewrite_dummy()
  27. {
  28. G_warning("Vect_rewrite_line() %s",
  29. _("for this format/level not supported"));
  30. return -1;
  31. }
  32. static int delete_dummy()
  33. {
  34. G_warning("Vect_delete_line() %s",
  35. _("for this format/level not supported"));
  36. return -1;
  37. }
  38. static int restore_dummy()
  39. {
  40. G_warning("Vect_restore_line() %s",
  41. _("for this format/level not supported"));
  42. return -1;
  43. }
  44. #if !defined HAVE_OGR || !defined HAVE_POSTGRES
  45. static int format()
  46. {
  47. G_fatal_error(_("Requested format is not compiled in this version"));
  48. return 0;
  49. }
  50. static off_t format_l()
  51. {
  52. G_fatal_error(_("Requested format is not compiled in this version"));
  53. return 0;
  54. }
  55. #endif
  56. static off_t (*Vect_write_line_array[][3]) () = {
  57. {
  58. write_dummy, V1_write_line_nat, V2_write_line_nat}
  59. #ifdef HAVE_OGR
  60. , {
  61. write_dummy, V1_write_line_ogr, V2_write_line_sfa}
  62. , {
  63. write_dummy, V1_write_line_ogr, V2_write_line_sfa}
  64. #else
  65. , {
  66. write_dummy, format_l, format_l}
  67. , {
  68. write_dummy, format_l, format_l}
  69. #endif
  70. #ifdef HAVE_POSTGRES
  71. , {
  72. write_dummy, V1_write_line_pg, V2_write_line_sfa}
  73. #else
  74. , {
  75. write_dummy, format_l, format_l}
  76. #endif
  77. };
  78. static off_t (*Vect_rewrite_line_array[][3]) () = {
  79. {
  80. rewrite_dummy, V1_rewrite_line_nat, V2_rewrite_line_nat}
  81. #ifdef HAVE_OGR
  82. , {
  83. rewrite_dummy, V1_rewrite_line_ogr, V2_rewrite_line_sfa}
  84. , {
  85. rewrite_dummy, V1_rewrite_line_ogr, V2_rewrite_line_sfa}
  86. #else
  87. , {
  88. rewrite_dummy, format_l, format_l}
  89. , {
  90. rewrite_dummy, format_l, format_l}
  91. #endif
  92. #ifdef HAVE_POSTGRES
  93. , {
  94. rewrite_dummy, V1_rewrite_line_pg, V2_rewrite_line_sfa}
  95. #else
  96. , {
  97. rewrite_dummy, format_l, format_l}
  98. #endif
  99. };
  100. static int (*Vect_delete_line_array[][3]) () = {
  101. {
  102. delete_dummy, V1_delete_line_nat, V2_delete_line_nat}
  103. #ifdef HAVE_OGR
  104. , {
  105. delete_dummy, V1_delete_line_ogr, V2_delete_line_sfa}
  106. , {
  107. delete_dummy, V1_delete_line_ogr, V2_delete_line_sfa}
  108. #else
  109. , {
  110. delete_dummy, format, format}
  111. , {
  112. delete_dummy, format, format}
  113. #endif
  114. #ifdef HAVE_POSTGRES
  115. , {
  116. delete_dummy, V1_delete_line_pg, V2_delete_line_sfa}
  117. #else
  118. , {
  119. delete_dummy, format, format}
  120. #endif
  121. };
  122. static int (*Vect_restore_line_array[][3]) () = {
  123. {
  124. restore_dummy, restore_dummy, V2_restore_line_nat}
  125. #ifdef HAVE_OGR
  126. , {
  127. restore_dummy, restore_dummy, restore_dummy}
  128. , {
  129. restore_dummy, restore_dummy, restore_dummy}
  130. #else
  131. , {
  132. restore_dummy, format, format}
  133. , {
  134. restore_dummy, format, format}
  135. #endif
  136. #ifdef HAVE_POSTGRES
  137. , {
  138. restore_dummy, restore_dummy, restore_dummy}
  139. #else
  140. , {
  141. restore_dummy, format, format}
  142. #endif
  143. };
  144. /*!
  145. \brief Writes new feature
  146. New feature is written to the end of file (in the case of native
  147. format). Vector map topology is not required.
  148. Calls G_fatal_error() when vector map is not opened.
  149. \param Map pointer to Map_info structure
  150. \param type feature type (see dig_defines.h for supported types)
  151. \param points ointer to line_pnts structure (feature geometry)
  152. \param cats pointer to line_cats structure (feature categories)
  153. \return new feature id (on level 2)
  154. \return offset into file where the feature starts (on level 1)
  155. \return -1 on error
  156. */
  157. off_t Vect_write_line(struct Map_info *Map, int type,
  158. const struct line_pnts *points, const struct line_cats *cats)
  159. {
  160. off_t offset;
  161. G_debug(3, "Vect_write_line(): name = %s, format = %d, level = %d",
  162. Map->name, Map->format, Map->level);
  163. if (!VECT_OPEN(Map))
  164. G_fatal_error(_("Unable to write feature, vector map is not opened"));
  165. if (!(Map->plus.update_cidx)) {
  166. Map->plus.cidx_up_to_date = FALSE;
  167. }
  168. offset =
  169. (*Vect_write_line_array[Map->format][Map->level]) (Map, type, points,
  170. cats);
  171. /*
  172. if (offset == -1)
  173. G_fatal_error(_("Unable to write feature (negative offset)"));
  174. */
  175. /* note: returns new feature id on level 2 and file offset on
  176. level 1 */
  177. return offset;
  178. }
  179. /*!
  180. \brief Rewrites feature info at the given offset.
  181. Vector map must be opened with full topology (level 2).
  182. The number of points or cats or type may change. If necessary, the
  183. old feature is deleted and new is written.
  184. This function calls G_fatal_error() on error.
  185. \param Map pointer to Map_info structure
  186. \param line feature id
  187. \param type feature type (GV_POINT, GV_LINE, ...)
  188. \param points feature geometry
  189. \param cats feature categories
  190. \return feature offset
  191. \return -1 on error
  192. */
  193. off_t Vect_rewrite_line(struct Map_info *Map, int line, int type,
  194. const struct line_pnts *points, const struct line_cats *cats)
  195. {
  196. off_t ret, offset;
  197. if (!VECT_OPEN(Map))
  198. G_fatal_error(_("Unable to rewrite feature, vector map is not opened"));
  199. if (!(Map->plus.update_cidx)) {
  200. Map->plus.cidx_up_to_date = FALSE;
  201. }
  202. offset = Map->plus.Line[line]->offset;
  203. G_debug(3, "Vect_rewrite_line(): name = %s, line = %d offset = %lu",
  204. Map->name, line, offset);
  205. ret = (*Vect_rewrite_line_array[Map->format][Map->level]) (Map, line, type,
  206. offset,
  207. points, cats);
  208. /*
  209. if (ret == -1)
  210. G_fatal_error(_("Unable to rewrite feature %d"), line);
  211. */
  212. return ret;
  213. }
  214. /*!
  215. \brief Delete feature
  216. Vector map must be opened with full topology (level 2).
  217. This function calls G_fatal_error() on error.
  218. \param Map pointer to Map_info structure
  219. \param line feature id
  220. \return 0 on success
  221. \return -1 on error
  222. */
  223. int Vect_delete_line(struct Map_info *Map, int line)
  224. {
  225. int ret;
  226. G_debug(3, "Vect_delete_line(): name = %s, line = %d", Map->name, line);
  227. if (Map->level < 2) {
  228. G_fatal_error(_("Unable to delete feature %d, "
  229. "vector map <%s> is not opened on topology level"),
  230. line, Map->name);
  231. }
  232. if (Map->mode != GV_MODE_RW && Map->mode != GV_MODE_WRITE) {
  233. G_fatal_error(_("Unable to delete feature %d, "
  234. "vector map <%s> is not opened in 'write' mode"),
  235. line, Map->name);
  236. }
  237. if (!(Map->plus.update_cidx)) {
  238. Map->plus.cidx_up_to_date = FALSE;
  239. }
  240. ret = (*Vect_delete_line_array[Map->format][Map->level]) (Map, line);
  241. /*
  242. if (ret == -1)
  243. G_fatal_error(_("Unable to delete feature id %d from vector map <%s>"),
  244. line, Vect_get_full_name(Map));
  245. */
  246. return ret;
  247. }
  248. /*!
  249. \brief Restore previously deleted feature
  250. Vector map must be opened with full topology (level 2).
  251. This function calls G_fatal_error() on error.
  252. \param Map pointer to Map_info structure
  253. \param line feature id to be restored
  254. \return 0 on success
  255. \return -1 on error
  256. */
  257. int Vect_restore_line(struct Map_info *Map, int line, off_t offset)
  258. {
  259. int ret;
  260. G_debug(3, "Vect_restore_line(): name = %s, line = %d", Map->name, line);
  261. if (Map->level < 2) {
  262. G_fatal_error(_("Unable to restore feature %d, "
  263. "vector map <%s> is not opened on topology level"),
  264. line, Map->name);
  265. }
  266. if (Map->mode != GV_MODE_RW && Map->mode != GV_MODE_WRITE) {
  267. G_fatal_error(_("Unable to restore feature %d, "
  268. "vector map <%s> is not opened in 'write' mode"),
  269. line, Map->name);
  270. }
  271. if (!(Map->plus.update_cidx)) {
  272. Map->plus.cidx_up_to_date = 0;
  273. }
  274. ret = (*Vect_restore_line_array[Map->format][Map->level]) (Map, line, offset);
  275. /*
  276. if (ret == -1)
  277. G_fatal_error(_("Unable to restore feature %d from vector map <%s>"),
  278. line, Map->name);
  279. */
  280. return ret;
  281. }