geos_to_wktb.c 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279
  1. /*!
  2. \file lib/vector/Vlib/geos_to_wktb.c
  3. \brief Vector library - GEOS powered WKT and WKB export
  4. Higher level functions for reading/writing/manipulating vectors.
  5. (C) 2015 by the GRASS Development Team
  6. This program is free software under the GNU General Public License
  7. (>=v2). Read the file COPYING that comes with GRASS for details.
  8. \author Soeren Gebbert <soerengebbert googlemail.com>
  9. */
  10. #include <stdlib.h>
  11. #include <grass/vector.h>
  12. #include <grass/glocale.h>
  13. #ifdef HAVE_GEOS
  14. /*!
  15. \brief Read vector area and return it as Well Known Binary (WKB)
  16. unsigned char array
  17. \param Map pointer to Map_info structure
  18. \param area area id
  19. \param size The size of the returned unsigned char array
  20. \return pointer to unsigned char array
  21. \return NULL on error
  22. */
  23. unsigned char *Vect_read_area_to_wkb(struct Map_info * Map, int area, size_t *size)
  24. {
  25. static int init = 0;
  26. /* The writer is static for performance reasons */
  27. static GEOSWKBWriter *writer = NULL;
  28. unsigned char *wkb = NULL;
  29. if(init == 0) {
  30. initGEOS(NULL, NULL);
  31. writer = GEOSWKBWriter_create();
  32. init += 1;
  33. }
  34. GEOSWKBWriter_setOutputDimension(writer, 2);
  35. GEOSGeometry *geom = Vect_read_area_geos(Map, area);
  36. if(!geom) {
  37. return(NULL);
  38. }
  39. wkb = GEOSWKBWriter_write(writer, geom, size);
  40. GEOSGeom_destroy(geom);
  41. return(wkb);
  42. }
  43. /*!
  44. \brief Read vector area and return it as Well Known Text (WKT)
  45. unsigned char array
  46. \param Map pointer to Map_info structure
  47. \param area area id
  48. \param size The size of the returned unsigned char array
  49. \return pointer to char array
  50. \return NULL on error
  51. */
  52. char *Vect_read_area_to_wkt(struct Map_info * Map, int area)
  53. {
  54. static int init = 0;
  55. /* The writer is static for performance reasons */
  56. static GEOSWKTWriter *writer = NULL;
  57. char *wkt = NULL;
  58. if(init == 0) {
  59. initGEOS(NULL, NULL);
  60. writer = GEOSWKTWriter_create();
  61. init += 1;
  62. }
  63. GEOSWKTWriter_setOutputDimension(writer, 2);
  64. GEOSGeometry *geom = Vect_read_area_geos(Map, area);
  65. if(!geom) {
  66. return(NULL);
  67. }
  68. wkt = GEOSWKTWriter_write(writer, geom);
  69. GEOSGeom_destroy(geom);
  70. return(wkt);
  71. }
  72. /*!
  73. \brief Read a Well Known Binary (WKB) representation of
  74. a given feature id.
  75. This function reads a specific feature and converts it into a
  76. WKB representation. line_pnts and line_cats structures can be provided
  77. to store the result of the read operation. That is meaningful in case
  78. the category values of the feature are needed.
  79. This function is not thread safe, it uses static variables for speedup.
  80. Supported feature types:
  81. - GV_POINT -> POINT
  82. - GV_CENTROID -> POINT
  83. - GV_LINE -> LINESTRING
  84. - GV_BOUNDARY -> LINEARRING
  85. \param Map pointer to Map_info structure
  86. \param line_p pointer to line_pnts structure to use, or NULL
  87. \param line_c pointer to line_cats structure to use, or NULL
  88. \param line The id of the feature to read
  89. \param size The size of the returned unsigned char array
  90. \return pointer to unsigned char array
  91. \return NULL on error
  92. */
  93. unsigned char *Vect_read_line_to_wkb(const struct Map_info *Map,
  94. struct line_pnts *line_p,
  95. struct line_cats *line_c,
  96. int line, size_t *size,
  97. int *error)
  98. {
  99. static int init = 0;
  100. /* The writer is static for performance reasons */
  101. static GEOSWKBWriter *writer = NULL;
  102. unsigned char *wkb = NULL;
  103. int destroy_line = 0, destroy_cats = 0;
  104. if(init == 0) {
  105. initGEOS(NULL, NULL);
  106. writer = GEOSWKBWriter_create();
  107. init += 1;
  108. }
  109. if(line_p == NULL) {
  110. destroy_line = 1;
  111. line_p = Vect_new_line_struct();
  112. }
  113. if(line_c == NULL) {
  114. destroy_cats = 1;
  115. line_c = Vect_new_cats_struct();
  116. }
  117. int f_type = Vect_read_line(Map, line_p, line_c, line);
  118. /* Save the error state */
  119. *error = f_type;
  120. if(f_type < 0)
  121. return(NULL);
  122. GEOSWKBWriter_setOutputDimension(writer, Vect_is_3d(Map) ? 3 : 2);
  123. GEOSGeometry *geom = Vect_line_to_geos(line_p, f_type, Vect_is_3d(Map));
  124. if(destroy_cats == 1)
  125. Vect_destroy_cats_struct(line_c);
  126. if(destroy_line == 1)
  127. Vect_destroy_line_struct(line_p);
  128. if(!geom) {
  129. return(NULL);
  130. }
  131. wkb = GEOSWKBWriter_write(writer, geom, size);
  132. GEOSGeom_destroy(geom);
  133. return(wkb);
  134. }
  135. /*!
  136. \brief Create a Well Known Binary (WKB) representation of
  137. given feature type from points.
  138. This function is not thread safe, it uses static variables for speedup.
  139. Supported feature types:
  140. - GV_POINT -> POINT
  141. - GV_CENTROID -> POINT
  142. - GV_LINE -> LINESTRING
  143. - GV_BOUNDARY -> LINEARRING
  144. \param points pointer to line_pnts structure
  145. \param type feature type (see supported types)
  146. \param with_z Set to 1 if the feature is 3d, 0 otherwise
  147. \param size The size of the returned byte array
  148. \return pointer to char array
  149. \return NULL on error
  150. */
  151. unsigned char *Vect_line_to_wkb(const struct line_pnts *points,
  152. int type, int with_z, size_t *size)
  153. {
  154. static int init = 0;
  155. /* The writer is static for performance reasons */
  156. static GEOSWKBWriter *writer = NULL;
  157. unsigned char *wkb = NULL;
  158. if(init == 0) {
  159. initGEOS(NULL, NULL);
  160. writer = GEOSWKBWriter_create();
  161. init += 1;
  162. }
  163. GEOSWKBWriter_setOutputDimension(writer, with_z ? 3 : 2);
  164. GEOSGeometry *geom = Vect_line_to_geos(points, type, with_z);
  165. if(!geom) {
  166. return(NULL);
  167. }
  168. wkb = GEOSWKBWriter_write(writer, geom, size);
  169. GEOSGeom_destroy(geom);
  170. return(wkb);
  171. }
  172. /*!
  173. \brief Create a Well Known Text (WKT) representation of
  174. given feature type from points.
  175. This function is not thread safe, it uses static variables for speedup.
  176. Supported types:
  177. - GV_POINT -> POINT
  178. - GV_CENTROID -> POINT
  179. - GV_LINE -> LINESTRING
  180. - GV_BOUNDARY -> LINEARRING
  181. \param points pointer to line_pnts structure
  182. \param type feature type (see supported types)
  183. \param with_z Set to 1 if the feature is 3d, 0 otherwise
  184. \return pointer to char array
  185. \return NULL on error
  186. */
  187. char *Vect_line_to_wkt(const struct line_pnts *points,
  188. int type, int with_z)
  189. {
  190. static int init = 0;
  191. /* The writer is static for performance reasons */
  192. static GEOSWKTWriter *writer = NULL;
  193. char *wkt = NULL;
  194. if(init == 0) {
  195. initGEOS(NULL, NULL);
  196. writer = GEOSWKTWriter_create();
  197. init += 1;
  198. }
  199. GEOSWKTWriter_setOutputDimension(writer, with_z ? 3 : 2);
  200. GEOSGeometry *geom = Vect_line_to_geos(points, type, with_z);
  201. if(!geom) {
  202. return(NULL);
  203. }
  204. wkt = GEOSWKTWriter_write(writer, geom);
  205. GEOSGeom_destroy(geom);
  206. return(wkt);
  207. }
  208. #endif /* HAVE_GEOS */