GRASS GIS 8 Programmer's Manual  8.5.0dev(2024)-38f5cf43d1
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 size The size of the returned unsigned char array
83  \param trim Set the number trimming option on, With trim set to true, the
84  writer will strip trailing 0's from the output coordinates.
85 
86  \return pointer to string (allocated)
87  \return NULL on error
88  */
89 char *Vect_read_area_to_wkt2(struct Map_info *Map, int area, bool trim)
90 {
91  static int init = 0;
92 
93  /* The writer is static for performance reasons */
94  static GEOSWKTWriter *writer = NULL;
95  char *wkt = NULL;
96 
97  if (init == 0) {
98  initGEOS(NULL, NULL);
99  writer = GEOSWKTWriter_create();
100  init += 1;
101  }
102 
103  GEOSWKTWriter_setOutputDimension(writer, 2);
104  GEOSWKTWriter_setTrim(writer, trim);
105 
106  GEOSGeometry *geom = Vect_read_area_geos(Map, area);
107 
108  if (!geom) {
109  return NULL;
110  }
111 
112  wkt = GEOSWKTWriter_write(writer, geom);
113  char *wkt_out = G_store(wkt);
114 
115  GEOSGeom_destroy(geom);
116  GEOSFree(wkt);
117 
118  return wkt_out;
119 }
120 
121 /*!
122  \brief Read a Well Known Binary (WKB) representation of
123  a given feature id.
124 
125  This function reads a specific feature and converts it into a
126  WKB representation. line_pnts and line_cats structures can be provided
127  to store the result of the read operation. That is meaningful in case
128  the category values of the feature are needed.
129  This function is not thread safe, it uses static variables for speedup.
130 
131  Supported feature types:
132  - GV_POINT -> POINT
133  - GV_CENTROID -> POINT
134  - GV_LINE -> LINESTRING
135  - GV_BOUNDARY -> LINEARRING
136 
137  \param Map pointer to Map_info structure
138  \param line_p pointer to line_pnts structure to use, or NULL
139  \param line_c pointer to line_cats structure to use, or NULL
140  \param line The id of the feature to read
141  \param size The size of the returned unsigned char array
142 
143  \return pointer to unsigned char array
144  \return NULL on error
145  */
146 unsigned char *Vect_read_line_to_wkb(struct Map_info *Map,
147  struct line_pnts *line_p,
148  struct line_cats *line_c, int line,
149  size_t *size, int *error)
150 {
151  static int init = 0;
152 
153  /* The writer is static for performance reasons */
154  static GEOSWKBWriter *writer = NULL;
155  unsigned char *wkb = NULL;
156  int destroy_line = 0, destroy_cats = 0;
157 
158  if (init == 0) {
159  initGEOS(NULL, NULL);
160  writer = GEOSWKBWriter_create();
161  init += 1;
162  }
163 
164  if (line_p == NULL) {
165  destroy_line = 1;
166  line_p = Vect_new_line_struct();
167  }
168 
169  if (line_c == NULL) {
170  destroy_cats = 1;
171  line_c = Vect_new_cats_struct();
172  }
173 
174  int f_type = Vect_read_line(Map, line_p, line_c, line);
175 
176  /* Save the error state */
177  *error = f_type;
178 
179  if (f_type < 0)
180  return (NULL);
181 
182  GEOSWKBWriter_setOutputDimension(writer, Vect_is_3d(Map) ? 3 : 2);
183 
184  GEOSGeometry *geom = Vect_line_to_geos(line_p, f_type, Vect_is_3d(Map));
185 
186  if (destroy_cats == 1)
187  Vect_destroy_cats_struct(line_c);
188 
189  if (destroy_line == 1)
190  Vect_destroy_line_struct(line_p);
191 
192  if (!geom) {
193  return (NULL);
194  }
195 
196  wkb = GEOSWKBWriter_write(writer, geom, size);
197 
198  GEOSGeom_destroy(geom);
199 
200  return (wkb);
201 }
202 
203 /*!
204  \brief Create a Well Known Binary (WKB) representation of
205  given feature type from points.
206 
207  This function is not thread safe, it uses static variables for speedup.
208 
209  Supported feature types:
210  - GV_POINT -> POINT
211  - GV_CENTROID -> POINT
212  - GV_LINE -> LINESTRING
213  - GV_BOUNDARY -> LINEARRING
214 
215  \param points pointer to line_pnts structure
216  \param type feature type (see supported types)
217  \param with_z Set to 1 if the feature is 3d, 0 otherwise
218  \param size The size of the returned byte array
219 
220  \return pointer to string (allocated)
221  \return NULL on error
222  */
223 unsigned char *Vect_line_to_wkb(const struct line_pnts *points, int type,
224  int with_z, size_t *size)
225 {
226  static int init = 0;
227 
228  /* The writer is static for performance reasons */
229  static GEOSWKBWriter *writer = NULL;
230  unsigned char *wkb = NULL;
231 
232  if (init == 0) {
233  initGEOS(NULL, NULL);
234  writer = GEOSWKBWriter_create();
235  init += 1;
236  }
237 
238  GEOSWKBWriter_setOutputDimension(writer, with_z ? 3 : 2);
239 
240  GEOSGeometry *geom = Vect_line_to_geos(points, type, with_z);
241 
242  if (!geom) {
243  return (NULL);
244  }
245 
246  wkb = GEOSWKBWriter_write(writer, geom, size);
247 
248  GEOSGeom_destroy(geom);
249 
250  return (wkb);
251 }
252 
253 /*!
254  \brief Create a Well Known Text (WKT) representation of
255  given feature type from points.
256 
257  Calls Vect_line_to_wkt2() with trim set to false.
258  */
259 char *Vect_line_to_wkt(const struct line_pnts *points, int type, bool with_z)
260 {
261  return Vect_line_to_wkt2(points, type, with_z, false);
262 }
263 
264 /*!
265  \brief Create a Well Known Text (WKT) representation of
266  given feature type from points.
267 
268  This function is not thread safe, it uses static variables for speedup.
269 
270  Supported types:
271  - GV_POINT -> POINT
272  - GV_CENTROID -> POINT
273  - GV_LINE -> LINESTRING
274  - GV_BOUNDARY -> LINEARRING
275 
276  \param points pointer to line_pnts structure
277  \param type feature type (see supported types)
278  \param with_z Set to true if the feature is 3d, false otherwise
279  \param trim Set the number trimming option on, With trim set to true, the
280  writer will strip trailing 0's from the output coordinates.
281 
282  \return pointer to char array
283  \return NULL on error
284  */
285 char *Vect_line_to_wkt2(const struct line_pnts *points, int type, bool with_z,
286  bool trim)
287 {
288  static int init = 0;
289 
290  /* The writer is static for performance reasons */
291  static GEOSWKTWriter *writer = NULL;
292  char *wkt = NULL;
293 
294  if (init == 0) {
295  initGEOS(NULL, NULL);
296  writer = GEOSWKTWriter_create();
297  init += 1;
298  }
299 
300  GEOSWKTWriter_setOutputDimension(writer, with_z ? 3 : 2);
301  GEOSWKTWriter_setTrim(writer, trim);
302 
303  GEOSGeometry *geom = Vect_line_to_geos(points, type, with_z);
304 
305  if (!geom) {
306  return NULL;
307  }
308 
309  wkt = GEOSWKTWriter_write(writer, geom);
310  char *wkt_out = G_store(wkt);
311 
312  GEOSGeom_destroy(geom);
313  GEOSFree(wkt);
314 
315  return wkt_out;
316 }
317 
318 #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:146
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:223
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:89
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:285
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:259
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