GRASS 8 Programmer's Manual  8.5.0dev(2025)-d272f2f102
geos_to_wktb.c
Go to the documentation of this file.
1 /*!
2  \file lib/vector/Vlib/geos_to_wktb.c
3 
4  \brief Vector library - GEOS powered WKT and WKB export
5 
6  Higher level functions for reading/writing/manipulating vectors.
7 
8  (C) 2015 by the GRASS Development Team
9 
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 
13  \author Soeren Gebbert <soerengebbert googlemail.com>
14  */
15 
16 #include <stdbool.h>
17 #include <stdlib.h>
18 #include <grass/vector.h>
19 #include <grass/glocale.h>
20 
21 #ifdef HAVE_GEOS
22 
23 /*!
24  \brief Read vector area and return it as Well Known Binary (WKB)
25  unsigned char array
26 
27  \param Map pointer to Map_info structure
28  \param area area id
29  \param size The size of the returned unsigned char array
30 
31  \return pointer to unsigned char array
32  \return NULL on error
33  */
34 unsigned char *Vect_read_area_to_wkb(struct Map_info *Map, int area,
35  size_t *size)
36 {
37  static int init = 0;
38 
39  /* The writer is static for performance reasons */
40  static GEOSWKBWriter *writer = NULL;
41  unsigned char *wkb = NULL;
42 
43  if (init == 0) {
44  initGEOS(NULL, NULL);
45  writer = GEOSWKBWriter_create();
46  init += 1;
47  }
48 
49  GEOSWKBWriter_setOutputDimension(writer, 2);
50 
51  GEOSGeometry *geom = Vect_read_area_geos(Map, area);
52 
53  if (!geom) {
54  return (NULL);
55  }
56 
57  wkb = GEOSWKBWriter_write(writer, geom, size);
58 
59  GEOSGeom_destroy(geom);
60 
61  return (wkb);
62 }
63 
64 /*!
65  \brief Read vector area and return it as Well Known Text (WKT)
66  unsigned char array
67 
68  Calls Vect_read_area_to_wkt2() with trim set to false.
69 
70  */
71 char *Vect_read_area_to_wkt(struct Map_info *Map, int area)
72 {
73  return Vect_read_area_to_wkt2(Map, area, false);
74 }
75 
76 /*!
77  \brief Read vector area and return it as Well Known Text (WKT)
78  unsigned char array
79 
80  \param Map pointer to Map_info structure
81  \param area area id
82  \param trim Set the number trimming option on, With trim set to true, the
83  writer will strip trailing 0's from the output coordinates.
84 
85  \return pointer to string (allocated)
86  \return NULL on error
87  */
88 char *Vect_read_area_to_wkt2(struct Map_info *Map, int area, bool trim)
89 {
90  static int init = 0;
91 
92  /* The writer is static for performance reasons */
93  static GEOSWKTWriter *writer = NULL;
94  char *wkt = NULL;
95 
96  if (init == 0) {
97  initGEOS(NULL, NULL);
98  writer = GEOSWKTWriter_create();
99  init += 1;
100  }
101 
102  GEOSWKTWriter_setOutputDimension(writer, 2);
103  GEOSWKTWriter_setTrim(writer, trim);
104 
105  GEOSGeometry *geom = Vect_read_area_geos(Map, area);
106 
107  if (!geom) {
108  return NULL;
109  }
110 
111  wkt = GEOSWKTWriter_write(writer, geom);
112  char *wkt_out = G_store(wkt);
113 
114  GEOSGeom_destroy(geom);
115  GEOSFree(wkt);
116 
117  return wkt_out;
118 }
119 
120 /*!
121  \brief Read a Well Known Binary (WKB) representation of
122  a given feature id.
123 
124  This function reads a specific feature and converts it into a
125  WKB representation. line_pnts and line_cats structures can be provided
126  to store the result of the read operation. That is meaningful in case
127  the category values of the feature are needed.
128  This function is not thread safe, it uses static variables for speedup.
129 
130  Supported feature types:
131  - GV_POINT -> POINT
132  - GV_CENTROID -> POINT
133  - GV_LINE -> LINESTRING
134  - GV_BOUNDARY -> LINEARRING
135 
136  \param Map pointer to Map_info structure
137  \param line_p pointer to line_pnts structure to use, or NULL
138  \param line_c pointer to line_cats structure to use, or NULL
139  \param line The id of the feature to read
140  \param size The size of the returned unsigned char array
141 
142  \return pointer to unsigned char array
143  \return NULL on error
144  */
145 unsigned char *Vect_read_line_to_wkb(struct Map_info *Map,
146  struct line_pnts *line_p,
147  struct line_cats *line_c, int line,
148  size_t *size, int *error)
149 {
150  static int init = 0;
151 
152  /* The writer is static for performance reasons */
153  static GEOSWKBWriter *writer = NULL;
154  unsigned char *wkb = NULL;
155  int destroy_line = 0, destroy_cats = 0;
156 
157  if (init == 0) {
158  initGEOS(NULL, NULL);
159  writer = GEOSWKBWriter_create();
160  init += 1;
161  }
162 
163  if (line_p == NULL) {
164  destroy_line = 1;
165  line_p = Vect_new_line_struct();
166  }
167 
168  if (line_c == NULL) {
169  destroy_cats = 1;
170  line_c = Vect_new_cats_struct();
171  }
172 
173  int f_type = Vect_read_line(Map, line_p, line_c, line);
174 
175  /* Save the error state */
176  *error = f_type;
177 
178  if (f_type < 0)
179  return (NULL);
180 
181  GEOSWKBWriter_setOutputDimension(writer, Vect_is_3d(Map) ? 3 : 2);
182 
183  GEOSGeometry *geom = Vect_line_to_geos(line_p, f_type, Vect_is_3d(Map));
184 
185  if (destroy_cats == 1)
186  Vect_destroy_cats_struct(line_c);
187 
188  if (destroy_line == 1)
189  Vect_destroy_line_struct(line_p);
190 
191  if (!geom) {
192  return (NULL);
193  }
194 
195  wkb = GEOSWKBWriter_write(writer, geom, size);
196 
197  GEOSGeom_destroy(geom);
198 
199  return (wkb);
200 }
201 
202 /*!
203  \brief Create a Well Known Binary (WKB) representation of
204  given feature type from points.
205 
206  This function is not thread safe, it uses static variables for speedup.
207 
208  Supported feature types:
209  - GV_POINT -> POINT
210  - GV_CENTROID -> POINT
211  - GV_LINE -> LINESTRING
212  - GV_BOUNDARY -> LINEARRING
213 
214  \param points pointer to line_pnts structure
215  \param type feature type (see supported types)
216  \param with_z Set to 1 if the feature is 3d, 0 otherwise
217  \param size The size of the returned byte array
218 
219  \return pointer to string (allocated)
220  \return NULL on error
221  */
222 unsigned char *Vect_line_to_wkb(const struct line_pnts *points, int type,
223  int with_z, size_t *size)
224 {
225  static int init = 0;
226 
227  /* The writer is static for performance reasons */
228  static GEOSWKBWriter *writer = NULL;
229  unsigned char *wkb = NULL;
230 
231  if (init == 0) {
232  initGEOS(NULL, NULL);
233  writer = GEOSWKBWriter_create();
234  init += 1;
235  }
236 
237  GEOSWKBWriter_setOutputDimension(writer, with_z ? 3 : 2);
238 
239  GEOSGeometry *geom = Vect_line_to_geos(points, type, with_z);
240 
241  if (!geom) {
242  return (NULL);
243  }
244 
245  wkb = GEOSWKBWriter_write(writer, geom, size);
246 
247  GEOSGeom_destroy(geom);
248 
249  return (wkb);
250 }
251 
252 /*!
253  \brief Create a Well Known Text (WKT) representation of
254  given feature type from points.
255 
256  Calls Vect_line_to_wkt2() with trim set to false.
257  */
258 char *Vect_line_to_wkt(const struct line_pnts *points, int type, bool with_z)
259 {
260  return Vect_line_to_wkt2(points, type, with_z, false);
261 }
262 
263 /*!
264  \brief Create a Well Known Text (WKT) representation of
265  given feature type from points.
266 
267  This function is not thread safe, it uses static variables for speedup.
268 
269  Supported types:
270  - GV_POINT -> POINT
271  - GV_CENTROID -> POINT
272  - GV_LINE -> LINESTRING
273  - GV_BOUNDARY -> LINEARRING
274 
275  \param points pointer to line_pnts structure
276  \param type feature type (see supported types)
277  \param with_z Set to true if the feature is 3d, false otherwise
278  \param trim Set the number trimming option on, With trim set to true, the
279  writer will strip trailing 0's from the output coordinates.
280 
281  \return pointer to char array
282  \return NULL on error
283  */
284 char *Vect_line_to_wkt2(const struct line_pnts *points, int type, bool with_z,
285  bool trim)
286 {
287  static int init = 0;
288 
289  /* The writer is static for performance reasons */
290  static GEOSWKTWriter *writer = NULL;
291  char *wkt = NULL;
292 
293  if (init == 0) {
294  initGEOS(NULL, NULL);
295  writer = GEOSWKTWriter_create();
296  init += 1;
297  }
298 
299  GEOSWKTWriter_setOutputDimension(writer, with_z ? 3 : 2);
300  GEOSWKTWriter_setTrim(writer, trim);
301 
302  GEOSGeometry *geom = Vect_line_to_geos(points, type, with_z);
303 
304  if (!geom) {
305  return NULL;
306  }
307 
308  wkt = GEOSWKTWriter_write(writer, geom);
309  char *wkt_out = G_store(wkt);
310 
311  GEOSGeom_destroy(geom);
312  GEOSFree(wkt);
313 
314  return wkt_out;
315 }
316 
317 #endif /* HAVE_GEOS */
void init(double work[])
Definition: as177.c:61
#define NULL
Definition: ccmath.h:32
char * G_store(const char *)
Copy string to allocated memory.
Definition: strings.c:87
void Vect_destroy_line_struct(struct line_pnts *)
Frees all memory associated with a line_pnts structure, including the structure itself.
Definition: line.c:77
void Vect_destroy_cats_struct(struct line_cats *)
Frees all memory associated with line_cats structure, including the struct itself.
int Vect_read_line(struct Map_info *, struct line_pnts *, struct line_cats *, int)
Read vector feature (topological level required)
GEOSGeometry * Vect_read_area_geos(struct Map_info *, int)
Read vector area and stores it as GEOSGeometry instance (polygon)
Definition: geos.c:84
struct line_pnts * Vect_new_line_struct(void)
Creates and initializes a line_pnts structure.
Definition: line.c:45
GEOSGeometry * Vect_line_to_geos(const struct line_pnts *, int, int)
Create GEOSGeometry of given type from feature points.
Definition: geos.c:137
struct line_cats * Vect_new_cats_struct(void)
Creates and initializes line_cats structure.
int Vect_is_3d(struct Map_info *)
Check if vector map is 3D.
unsigned char * Vect_read_line_to_wkb(struct Map_info *Map, struct line_pnts *line_p, struct line_cats *line_c, int line, size_t *size, int *error)
Read a Well Known Binary (WKB) representation of a given feature id.
Definition: geos_to_wktb.c:145
char * Vect_read_area_to_wkt(struct Map_info *Map, int area)
Read vector area and return it as Well Known Text (WKT) unsigned char array.
Definition: geos_to_wktb.c:71
unsigned char * Vect_line_to_wkb(const struct line_pnts *points, int type, int with_z, size_t *size)
Create a Well Known Binary (WKB) representation of given feature type from points.
Definition: geos_to_wktb.c:222
unsigned char * Vect_read_area_to_wkb(struct Map_info *Map, int area, size_t *size)
Read vector area and return it as Well Known Binary (WKB) unsigned char array.
Definition: geos_to_wktb.c:34
char * Vect_read_area_to_wkt2(struct Map_info *Map, int area, bool trim)
Read vector area and return it as Well Known Text (WKT) unsigned char array.
Definition: geos_to_wktb.c:88
char * Vect_line_to_wkt2(const struct line_pnts *points, int type, bool with_z, bool trim)
Create a Well Known Text (WKT) representation of given feature type from points.
Definition: geos_to_wktb.c:284
char * Vect_line_to_wkt(const struct line_pnts *points, int type, bool with_z)
Create a Well Known Text (WKT) representation of given feature type from points.
Definition: geos_to_wktb.c:258
Vector map info.
Definition: dig_structs.h:1243
Feature category info.
Definition: dig_structs.h:1677
Feature geometry info - coordinates.
Definition: dig_structs.h:1651
struct GEOSGeom_t GEOSGeometry
Definition: vector.h:9