GRASS GIS 8 Programmer's Manual  8.5.0dev(2025)-299a28a7d0
write_ogr.c
Go to the documentation of this file.
1 /*!
2  \file lib/vector/Vlib/write_ogr.c
3 
4  \brief Vector library - write vector feature (OGR format)
5 
6  Higher level functions for reading/writing/manipulating vectors.
7 
8  Partly inspired by v.out.ogr's code.
9 
10  \todo How to deal with OGRNullFID
11 
12  (C) 2009-2013 by Martin Landa, and the GRASS Development Team
13 
14  This program is free software under the GNU General Public License
15  (>=v2). Read the file COPYING that comes with GRASS for details.
16 
17  \author Martin Landa <landa.martin gmail.com>
18  */
19 
20 #include <inttypes.h>
21 #include <grass/vector.h>
22 #include <grass/dbmi.h>
23 #include <grass/gprojects.h>
24 #include <grass/glocale.h>
25 
26 #ifdef HAVE_OGR
27 #include <ogr_api.h>
28 #include <cpl_string.h>
29 
30 static dbDriver *create_table(OGRLayerH, const struct field_info *);
31 static int create_ogr_layer(struct Map_info *, int);
32 static off_t write_feature(struct Map_info *, int, const struct line_pnts **,
33  int, const struct line_cats *);
34 static int write_attributes(dbDriver *, int, const struct field_info *,
35  OGRLayerH, OGRFeatureH);
36 static int sqltype_to_ogrtype(int);
37 #endif
38 
39 /*!
40  \brief Writes feature on level 1 (OGR interface)
41 
42  Note:
43  - centroids are not supported in OGR, pseudotopo holds virtual
44  centroids (it's coordinates determined from spatial index)
45  - unclosed boundaries are not supported in OGR, pseudotopo treats
46  polygons as boundaries
47 
48  Supported feature types:
49  - GV_POINT (written as wkbPoint)
50  - GV_LINE (wkbLineString)
51  - GV_BOUNDARY (wkbPolygon)
52  - GV_FACE (wkbPolygon25D)
53  - GV_KERNEL (wkbPoint25D)
54 
55  \param Map pointer to Map_info structure
56  \param type feature type
57  \param points pointer to line_pnts structure (feature geometry)
58  \param cats pointer to line_cats structure (feature categories)
59 
60  \return feature index in offset array (related to pseudo-topology)
61  \return -1 on error
62  */
63 off_t V1_write_line_ogr(struct Map_info *Map, int type,
64  const struct line_pnts *points,
65  const struct line_cats *cats)
66 {
67 #ifdef HAVE_OGR
68  return write_feature(Map, type, &points, 1, cats);
69 #else
70  G_fatal_error(_("GRASS is not compiled with OGR support"));
71  return -1;
72 #endif
73 }
74 
75 /*!
76  \brief Rewrites feature at the given offset on level 1 (OGR interface)
77 
78  This function simply calls V1_delete_line_ogr() and V1_write_line_ogr().
79 
80  \param Map pointer to Map_info structure
81  \param offset feature offset
82  \param type feature type (see V1_write_line_ogr() for supported types)
83  \param points pointer to line_pnts structure (feature geometry)
84  \param cats pointer to line_cats structure (feature categories)
85 
86  \return feature offset (rewritten feature)
87  \return -1 on error
88  */
89 off_t V1_rewrite_line_ogr(struct Map_info *Map, off_t offset, int type,
90  const struct line_pnts *points,
91  const struct line_cats *cats)
92 {
93  G_debug(3, "V1_rewrite_line_ogr(): type=%d offset=%" PRId64, type, offset);
94 #ifdef HAVE_OGR
95  if (type != V1_read_line_ogr(Map, NULL, NULL, offset)) {
96  G_warning(_("Unable to rewrite feature (incompatible feature types)"));
97  return -1;
98  }
99 
100  /* delete old */
101  V1_delete_line_ogr(Map, offset);
102 
103  return V1_write_line_ogr(Map, type, points, cats);
104 #else
105  G_fatal_error(_("GRASS is not compiled with OGR support"));
106  return -1;
107 #endif
108 }
109 
110 /*!
111  \brief Deletes feature at the given offset on level 1 (OGR interface)
112 
113  \param Map pointer Map_info structure
114  \param offset offset of feature to be deleted
115 
116  \return 0 on success
117  \return -1 on error
118  */
119 int V1_delete_line_ogr(struct Map_info *Map, off_t offset)
120 {
121 #ifdef HAVE_OGR
122  struct Format_info_ogr *ogr_info;
123 
124  G_debug(3, "V1_delete_line_ogr(), offset = %lu", (unsigned long)offset);
125 
126  ogr_info = &(Map->fInfo.ogr);
127 
128  if (!ogr_info->layer) {
129  G_warning(_("OGR layer not defined"));
130  return -1;
131  }
132 
133  if (offset >= ogr_info->offset.array_num) {
134  G_warning(_("Invalid offset (%" PRId64 ")"), offset);
135  return -1;
136  }
137 
138  if (OGR_L_DeleteFeature(ogr_info->layer, ogr_info->offset.array[offset]) !=
139  OGRERR_NONE) {
140  G_warning(_("Unable to delete feature"));
141  return -1;
142  }
143 
144  return 0;
145 #else
146  G_fatal_error(_("GRASS is not compiled with OGR support"));
147  return -1;
148 #endif
149 }
150 
151 #ifdef HAVE_OGR
152 /*!
153  \brief Writes area on topological level (OGR Simple Features
154  interface, internal use only)
155 
156  \param Map pointer to Map_info structure
157  \param points feature geometry (exterior + interior rings)
158  \param nparts number of parts including exterior ring
159  \param cats feature categories
160 
161  \return feature offset
162  \return -1 on error
163  */
164 off_t V2__write_area_ogr(struct Map_info *Map, const struct line_pnts **points,
165  int nparts, const struct line_cats *cats)
166 {
167  return write_feature(Map, GV_BOUNDARY, points, nparts, cats);
168 }
169 
170 dbDriver *create_table(OGRLayerH hLayer, const struct field_info *Fi)
171 {
172  int col, ncols;
173  int sqltype, ogrtype, length;
174 
175  const char *colname;
176 
177  dbDriver *driver;
178  dbHandle handle;
179  dbCursor cursor;
180  dbTable *table;
181  dbColumn *column;
182  dbString sql;
183 
184  OGRFieldDefnH hFieldDefn;
185  OGRFeatureDefnH hFeatureDefn;
186 
187  db_init_string(&sql);
188  db_init_handle(&handle);
189 
191  if (!driver) {
192  G_warning(_("Unable to start driver <%s>"), Fi->driver);
193  return NULL;
194  }
195  db_set_handle(&handle, Fi->database, NULL);
196  if (db_open_database(driver, &handle) != DB_OK) {
197  G_warning(_("Unable to open database <%s> by driver <%s>"),
198  Fi->database, Fi->driver);
200  return NULL;
201  }
202 
203  /* to get no data */
204  db_set_string(&sql, "select * from ");
205  db_append_string(&sql, Fi->table);
206  db_append_string(&sql, " where 0 = 1");
207 
208  if (db_open_select_cursor(driver, &sql, &cursor, DB_SEQUENTIAL) != DB_OK) {
209  G_warning(_("Unable to open select cursor: '%s'"), db_get_string(&sql));
211  return NULL;
212  }
213 
214  table = db_get_cursor_table(&cursor);
215  ncols = db_get_table_number_of_columns(table);
216 
217  hFeatureDefn = OGR_L_GetLayerDefn(hLayer);
218 
219  for (col = 0; col < ncols; col++) {
220  column = db_get_table_column(table, col);
221  colname = db_get_column_name(column);
222  sqltype = db_get_column_sqltype(column);
223  ogrtype = sqltype_to_ogrtype(sqltype);
224  length = db_get_column_length(column);
225 
226  if (strcmp(OGR_L_GetFIDColumn(hLayer), colname) == 0 ||
227  OGR_FD_GetFieldIndex(hFeatureDefn, colname) > -1) {
228  /* field already exists */
229  continue;
230  }
231 
232  hFieldDefn = OGR_Fld_Create(colname, ogrtype);
233  /* GDAL 1.9.0 (r22968) uses VARCHAR instead of CHAR */
234  if (ogrtype == OFTString && length > 0)
235  OGR_Fld_SetWidth(hFieldDefn, length);
236  if (OGR_L_CreateField(hLayer, hFieldDefn, TRUE) != OGRERR_NONE) {
237  G_warning(_("Creating field <%s> failed"), colname);
239  return NULL;
240  }
241 
242  OGR_Fld_Destroy(hFieldDefn);
243  }
244 
245  return driver;
246 }
247 
248 /*!
249  \brief Create new OGR layer in given OGR datasource (internal use only)
250 
251  V1_open_new_ogr() is required to be called before this function.
252 
253  List of currently supported types:
254  - GV_POINT (wkbPoint)
255  - GV_LINE (wkbLineString)
256  - GV_BOUNDARY (wkb_Polygon)
257  \param[in,out] Map pointer to Map_info structure
258  \param type feature type (GV_POINT, GV_LINE, ...)
259 
260  \return 0 success
261  \return -1 error
262  */
263 int create_ogr_layer(struct Map_info *Map, int type)
264 {
265  int ndblinks;
266  OGRLayerH Ogr_layer;
267  OGRSpatialReferenceH Ogr_spatial_ref;
268 
269  struct field_info *Fi;
270  struct Key_Value *projinfo, *projunits, *projepsg;
271  struct Format_info_ogr *ogr_info;
272 
273  OGRwkbGeometryType Ogr_geom_type;
274  char **Ogr_layer_options;
275 
276  ogr_info = &(Map->fInfo.ogr);
277 
278  if (!ogr_info->driver_name || !ogr_info->layer_name || !ogr_info->ds)
279  return -1;
280 
281  /* get spatial reference */
282  projinfo = G_get_projinfo();
283  projunits = G_get_projunits();
284  projepsg = G_get_projepsg();
285  Ogr_spatial_ref = GPJ_grass_to_osr2(projinfo, projunits, projepsg);
286  G_free_key_value(projinfo);
287  G_free_key_value(projunits);
288 
289  /* determine geometry type */
290  switch (type) {
291  case GV_POINT:
292  Ogr_geom_type = wkbPoint;
293  break;
294  case GV_LINE:
295  Ogr_geom_type = wkbLineString;
296  break;
297  case GV_BOUNDARY:
298  Ogr_geom_type = wkbPolygon;
299  break;
300  default:
301  G_warning(_("Unsupported geometry type (%d)"), type);
302  return -1;
303  }
304 
305  /* check creation options */
306  Ogr_layer_options = ogr_info->layer_options;
307  if (Vect_is_3d(Map)) {
308  if (strcmp(ogr_info->driver_name, "PostgreSQL") == 0) {
309  Ogr_layer_options = CSLSetNameValue(Ogr_layer_options, "DIM", "3");
310  }
311  }
312  else {
313  if (strcmp(ogr_info->driver_name, "PostgreSQL") == 0) {
314  Ogr_layer_options = CSLSetNameValue(Ogr_layer_options, "DIM", "2");
315  }
316  }
317 
318  /* create new OGR layer */
319  Ogr_layer =
320  OGR_DS_CreateLayer(ogr_info->ds, ogr_info->layer_name, Ogr_spatial_ref,
321  Ogr_geom_type, Ogr_layer_options);
322  CSLDestroy(Ogr_layer_options);
323  if (!Ogr_layer) {
324  G_warning(_("Unable to create OGR layer <%s> in '%s'"),
325  ogr_info->layer_name, ogr_info->dsn);
326  return -1;
327  }
328  ogr_info->layer = Ogr_layer;
329 
330  ndblinks = Vect_get_num_dblinks(Map);
331  if (ndblinks > 0) {
332  /* write also attributes */
333  Fi = Vect_get_dblink(Map, 0);
334  if (Fi) {
335  if (ndblinks > 1)
336  G_warning(_("More layers defined, using driver <%s> and "
337  "database <%s>"),
338  Fi->driver, Fi->database);
339  ogr_info->dbdriver = create_table(ogr_info->layer, Fi);
340  G_free(Fi);
341  }
342  else
343  G_warning(_("Database connection not defined. "
344  "Unable to write attributes."));
345  }
346 
347  if (OGR_L_TestCapability(ogr_info->layer, OLCTransactions) &&
348  (OGR_L_StartTransaction(ogr_info->layer) != OGRERR_NONE)) {
349  G_warning(_("OGR transaction with layer <%s> failed to start"),
350  ogr_info->layer_name);
351  return -1;
352  }
353 
354  return 0;
355 }
356 
357 /*!
358  \brief Write OGR feature
359 
360  \param Map pointer to Map_info structure
361  \param type feature type (GV_POINT, GV_LINE, ...)
362  \param bpoints feature geometry
363  \param cats feature categories
364  \param ipoints isle geometry for polygons on NULL
365  \param nisles number of isles
366 
367  \return feature offset into file
368  \return -1 on error
369  */
370 off_t write_feature(struct Map_info *Map, int type,
371  const struct line_pnts **p_points, int nparts,
372  const struct line_cats *cats)
373 {
374  int i, cat, ret;
375 
376  struct field_info *Fi;
377  const struct line_pnts *points;
378  struct Format_info_ogr *ogr_info;
379  struct Format_info_offset *offset_info;
380 
381  off_t offset;
382 
383  OGRGeometryH Ogr_geometry;
384  OGRFeatureH Ogr_feature;
385  OGRFeatureDefnH Ogr_featuredefn;
386  OGRwkbGeometryType Ogr_geom_type;
387 
388  ogr_info = &(Map->fInfo.ogr);
389  offset_info = &(ogr_info->offset);
390 
391  if (nparts < 1)
392  return -1;
393 
394  points = p_points[0]; /* feature geometry */
395 
396  if (!ogr_info->layer) {
397  /* create OGR layer if doesn't exist */
398  if (create_ogr_layer(Map, type) < 0)
399  return -1;
400  }
401 
402  if (!points)
403  return 0;
404 
405  cat = -1; /* no attributes to be written */
406  if (cats->n_cats > 0 && Vect_get_num_dblinks(Map) > 0) {
407  /* check for attributes */
408  Fi = Vect_get_dblink(Map, 0);
409  if (Fi) {
410  if (!Vect_cat_get(cats, Fi->number, &cat))
411  G_warning(_("No category defined for layer %d"), Fi->number);
412  if (cats->n_cats > 1) {
413  G_warning(_("Feature has more categories, using "
414  "category %d (from layer %d)"),
415  cat, cats->field[0]);
416  }
417  }
418  }
419 
420  Ogr_featuredefn = OGR_L_GetLayerDefn(ogr_info->layer);
421  Ogr_geom_type = OGR_FD_GetGeomType(Ogr_featuredefn);
422 
423  /* determine matching OGR feature geometry type */
424  if (type & (GV_POINT | GV_KERNEL)) {
425  if (Ogr_geom_type != wkbPoint && Ogr_geom_type != wkbPoint25D) {
426  G_warning(_("Feature is not a point. Skipping."));
427  return -1;
428  }
429  Ogr_geometry = OGR_G_CreateGeometry(wkbPoint);
430  }
431  else if (type & GV_LINE) {
432  if (Ogr_geom_type != wkbLineString &&
433  Ogr_geom_type != wkbLineString25D) {
434  G_warning(_("Feature is not a line. Skipping."));
435  return -1;
436  }
437  Ogr_geometry = OGR_G_CreateGeometry(wkbLineString);
438  }
439  else if (type & GV_BOUNDARY) {
440  if (Ogr_geom_type != wkbPolygon) {
441  G_warning(_("Feature is not a polygon. Skipping."));
442  return -1;
443  }
444  Ogr_geometry = OGR_G_CreateGeometry(wkbPolygon);
445  }
446  else if (type & GV_FACE) {
447  if (Ogr_geom_type != wkbPolygon25D) {
448  G_warning(_("Feature is not a face. Skipping."));
449  return -1;
450  }
451  Ogr_geometry = OGR_G_CreateGeometry(wkbPolygon25D);
452  }
453  else {
454  G_warning(_("Unsupported feature type (%d)"), type);
455  return -1;
456  }
457 
458  G_debug(3, "V1_write_line_ogr(): type = %d", type);
459 
460  if (Ogr_geom_type == wkbPolygon || Ogr_geom_type == wkbPolygon25D) {
461  int iring, npoints;
462 
463  /* add rings (first is exterior ring) */
464  for (iring = 0; iring < nparts; iring++) {
465  OGRGeometryH Ogr_ring;
466 
467  points = p_points[iring];
468  npoints = points->n_points - 1;
469  Ogr_ring = OGR_G_CreateGeometry(wkbLinearRing);
470  if (points->x[0] != points->x[npoints] ||
471  points->y[0] != points->y[npoints] ||
472  points->z[0] != points->z[npoints]) {
473  G_warning(_("Boundary is not closed. Feature skipped."));
474  return -1;
475  }
476 
477  /* add points */
478  for (i = 0; i < npoints; i++) {
479  OGR_G_AddPoint(Ogr_ring, points->x[i], points->y[i],
480  points->z[i]);
481  }
482  G_debug(4, " ring(%d): n_points = %d", iring, npoints);
483  OGR_G_AddGeometry(Ogr_geometry, Ogr_ring);
484  }
485  }
486  else {
487  for (i = 0; i < points->n_points; i++) {
488  OGR_G_AddPoint(Ogr_geometry, points->x[i], points->y[i],
489  points->z[i]);
490  }
491  G_debug(4, " n_points = %d", points->n_points);
492  }
493 
494  /* create feature & set geometry */
495  Ogr_feature = OGR_F_Create(Ogr_featuredefn);
496  OGR_F_SetGeometry(Ogr_feature, Ogr_geometry);
497 
498  /* write attributes */
499  if (cat > -1 && ogr_info->dbdriver) {
500  if (0 > write_attributes(ogr_info->dbdriver, cat, Fi, ogr_info->layer,
501  Ogr_feature))
502  G_warning(_("Unable to writes feature attributes"));
503  G_free(Fi);
504  }
505  /* write feature into layer */
506  ret = OGR_L_CreateFeature(ogr_info->layer, Ogr_feature);
507 
508  /* update offset array */
509  if (offset_info->array_num >= offset_info->array_alloc) {
510  offset_info->array_alloc += 1000;
511  offset_info->array = (int *)G_realloc(
512  offset_info->array, offset_info->array_alloc * sizeof(int));
513  }
514 
515  offset = offset_info->array_num;
516 
517  offset_info->array[offset_info->array_num++] =
518  (int)OGR_F_GetFID(Ogr_feature);
519  if (Ogr_geom_type == wkbPolygon || Ogr_geom_type == wkbPolygon25D) {
520  /* register exterior ring in offset array */
521  offset_info->array[offset_info->array_num++] = 0;
522  }
523 
524  /* destroy */
525  OGR_G_DestroyGeometry(Ogr_geometry);
526  OGR_F_Destroy(Ogr_feature);
527 
528  if (ret != OGRERR_NONE)
529  return -1;
530 
531  G_debug(3, "write_feature(): -> offset = %lu offset_num = %d cat = %d",
532  (unsigned long)offset, offset_info->array_num, cat);
533 
534  return offset;
535 }
536 
537 /*!
538  \brief Writes attributes
539 
540  \param driver pointer to dbDriver
541  \param Fi pointer to field_info struct
542  \param[in,out] Ogr_layer OGR layer
543  \param[in,out] Ogr_feature OGR feature to modify
544 
545  \return 1 on success
546  \return 0 no attributes
547  \return -1 on error
548  */
549 int write_attributes(dbDriver *driver, int cat, const struct field_info *Fi,
550  OGRLayerH Ogr_layer, OGRFeatureH Ogr_feature)
551 {
552  int j, ogrfieldnum;
553  char buf[2000];
554  int ncol, sqltype, ctype, ogrtype, more;
555  const char *fidcol, *colname;
556  dbTable *table;
557  dbString dbstring;
558  dbColumn *column;
559  dbCursor cursor;
560  dbValue *value;
561 
562  OGRFieldDefnH hFieldDefn;
563 
564  G_debug(3, "write_attributes(): cat = %d", cat);
565 
566  if (cat < 0) {
567  G_warning(_("Feature without category of layer %d"), Fi->number);
568  return 0;
569  }
570 
571  db_init_string(&dbstring);
572 
573  /* read & set attributes */
574  snprintf(buf, sizeof(buf), "SELECT * FROM %s WHERE %s = %d", Fi->table,
575  Fi->key, cat);
576  G_debug(4, "SQL: %s", buf);
577  db_set_string(&dbstring, buf);
578 
579  /* select data */
580  if (db_open_select_cursor(driver, &dbstring, &cursor, DB_SEQUENTIAL) !=
581  DB_OK) {
582  G_warning(_("Unable to select attributes for category %d"), cat);
583  return -1;
584  }
585 
586  if (db_fetch(&cursor, DB_NEXT, &more) != DB_OK) {
587  G_warning(_("Unable to fetch data from table <%s>"), Fi->table);
588  return -1;
589  }
590 
591  if (!more) {
592  G_warning(_("No database record for category %d, "
593  "no attributes will be written"),
594  cat);
595  return -1;
596  }
597 
598  fidcol = OGR_L_GetFIDColumn(Ogr_layer);
599 
600  table = db_get_cursor_table(&cursor);
601  ncol = db_get_table_number_of_columns(table);
602  for (j = 0; j < ncol; j++) {
603  column = db_get_table_column(table, j);
604  colname = db_get_column_name(column);
605  if (fidcol && *fidcol && strcmp(colname, fidcol) == 0) {
606  /* skip fid column */
607  continue;
608  }
609  value = db_get_column_value(column);
610  /* for debug only */
611  db_convert_column_value_to_string(column, &dbstring);
612  G_debug(3, "col %d : val = %s", j, db_get_string(&dbstring));
613 
614  sqltype = db_get_column_sqltype(column);
615  ctype = db_sqltype_to_Ctype(sqltype);
616  ogrtype = sqltype_to_ogrtype(sqltype);
617  G_debug(3, " colctype = %d", ctype);
618 
619  ogrfieldnum = OGR_F_GetFieldIndex(Ogr_feature, colname);
620  if (ogrfieldnum < 0) {
621  /* create field if not exists */
622  hFieldDefn = OGR_Fld_Create(colname, ogrtype);
623  if (OGR_L_CreateField(Ogr_layer, hFieldDefn, TRUE) != OGRERR_NONE)
624  G_warning(_("Unable to create field <%s>"), colname);
625  ogrfieldnum = OGR_F_GetFieldIndex(Ogr_feature, colname);
626  }
627 
628  /* Reset */
629  OGR_F_UnsetField(Ogr_feature, ogrfieldnum);
630 
631  /* prevent writing NULL values */
632  if (!db_test_value_isnull(value)) {
633  switch (ctype) {
634  case DB_C_TYPE_INT:
635  OGR_F_SetFieldInteger(Ogr_feature, ogrfieldnum,
636  db_get_value_int(value));
637  break;
638  case DB_C_TYPE_DOUBLE:
639  OGR_F_SetFieldDouble(Ogr_feature, ogrfieldnum,
640  db_get_value_double(value));
641  break;
642  case DB_C_TYPE_STRING:
643  OGR_F_SetFieldString(Ogr_feature, ogrfieldnum,
644  db_get_value_string(value));
645  break;
646  case DB_C_TYPE_DATETIME:
647  db_convert_column_value_to_string(column, &dbstring);
648  OGR_F_SetFieldString(Ogr_feature, ogrfieldnum,
649  db_get_string(&dbstring));
650  break;
651  default:
652  G_warning(_("Unsupported column type %d"), ctype);
653  break;
654  }
655  }
656  }
657 
658  db_close_cursor(&cursor);
659 
660  db_free_string(&dbstring);
661 
662  return 1;
663 }
664 
665 int sqltype_to_ogrtype(int sqltype)
666 {
667  int ctype, ogrtype;
668 
669  ctype = db_sqltype_to_Ctype(sqltype);
670 
671  switch (ctype) {
672  case DB_C_TYPE_INT:
673  ogrtype = OFTInteger;
674  break;
675  case DB_C_TYPE_DOUBLE:
676  ogrtype = OFTReal;
677  break;
678  case DB_C_TYPE_STRING:
679  ogrtype = OFTString;
680  break;
681  case DB_C_TYPE_DATETIME:
682  ogrtype = OFTString;
683  break;
684  default:
685  ogrtype = OFTString;
686  break;
687  }
688 
689  return ogrtype;
690 }
691 
692 #endif /* HAVE_OGR */
#define NULL
Definition: ccmath.h:32
#define DB_C_TYPE_INT
Definition: dbmi.h:108
#define DB_SEQUENTIAL
Definition: dbmi.h:123
#define DB_C_TYPE_STRING
Definition: dbmi.h:107
#define DB_C_TYPE_DOUBLE
Definition: dbmi.h:109
#define DB_OK
Definition: dbmi.h:71
#define DB_C_TYPE_DATETIME
Definition: dbmi.h:110
#define DB_NEXT
Definition: dbmi.h:114
int db_test_value_isnull(dbValue *)
Check of value is null.
Definition: value.c:26
const char * db_get_value_string(dbValue *)
Get string value.
Definition: value.c:92
dbValue * db_get_column_value(dbColumn *)
Returns column value for given column structure.
dbColumn * db_get_table_column(dbTable *, int)
Returns column structure for given table and column number.
int db_get_column_length(dbColumn *)
Get column's length.
double db_get_value_double(dbValue *)
Get double precision value.
Definition: value.c:50
int db_sqltype_to_Ctype(int)
Get C data type based on given SQL data type.
Definition: sqlCtype.c:24
dbDriver * db_start_driver(const char *)
Initialize a new dbDriver for db transaction.
Definition: start.c:51
int db_get_column_sqltype(dbColumn *)
Returns column sqltype for column.
int db_open_database(dbDriver *, dbHandle *)
Open database connection.
Definition: c_opendb.c:27
dbTable * db_get_cursor_table(dbCursor *)
Get table allocated by cursor.
Definition: cursor.c:67
int db_close_database_shutdown_driver(dbDriver *)
Close driver/database connection.
Definition: db.c:61
void db_free_string(dbString *)
Free allocated space for dbString.
Definition: string.c:150
int db_set_string(dbString *, const char *)
Inserts string to dbString (enlarge string)
Definition: string.c:41
int db_set_handle(dbHandle *, const char *, const char *)
Set handle (database and schema name)
Definition: handle.c:39
int db_get_value_int(dbValue *)
Get integer value.
Definition: value.c:38
void db_init_handle(dbHandle *)
Initialize handle (i.e database/schema)
Definition: handle.c:23
void db_init_string(dbString *)
Initialize dbString.
Definition: string.c:25
int db_close_cursor(dbCursor *)
Close cursor.
Definition: c_close_cur.c:27
int db_open_select_cursor(dbDriver *, dbString *, dbCursor *, int)
Open select cursor.
Definition: c_openselect.c:37
const char * db_get_column_name(dbColumn *)
Returns column name for given column.
int db_append_string(dbString *, const char *)
Append string to dbString.
Definition: string.c:205
int db_convert_column_value_to_string(dbColumn *, dbString *)
?
Definition: columnfmt.c:62
char * db_get_string(const dbString *)
Get string.
Definition: string.c:140
int db_fetch(dbCursor *, int, int *)
Fetch data from open cursor.
Definition: c_fetch.c:28
int db_get_table_number_of_columns(dbTable *)
Return the number of columns of the table.
void G_free(void *)
Free allocated memory.
Definition: gis/alloc.c:150
struct Key_Value * G_get_projinfo(void)
Gets projection information for location.
Definition: get_projinfo.c:61
#define G_realloc(p, n)
Definition: defs/gis.h:96
void void void void G_fatal_error(const char *,...) __attribute__((format(printf
struct Key_Value * G_get_projunits(void)
Gets units information for location.
Definition: get_projinfo.c:32
void G_warning(const char *,...) __attribute__((format(printf
void G_free_key_value(struct Key_Value *)
Free allocated Key_Value structure.
Definition: key_value1.c:104
struct Key_Value * G_get_projepsg(void)
Gets EPSG information for the current location.
Definition: get_projinfo.c:102
int G_debug(int, const char *,...) __attribute__((format(printf
OGRSpatialReferenceH GPJ_grass_to_osr2(const struct Key_Value *, const struct Key_Value *, const struct Key_Value *)
Converts a GRASS co-ordinate system to an OGRSpatialReferenceH object. EPSG code is preferred if avai...
Definition: convert.c:359
int Vect_cat_get(const struct line_cats *, int, int *)
Get first found category of given field.
int V1_read_line_ogr(struct Map_info *, struct line_pnts *, struct line_cats *, off_t)
Read feature from OGR layer at given offset (level 1 without topology)
Definition: read_ogr.c:179
int Vect_get_num_dblinks(struct Map_info *)
Get number of defined dblinks.
Definition: level_two.c:159
struct field_info * Vect_get_dblink(struct Map_info *, int)
Get information about link to database.
Definition: field.c:475
int Vect_is_3d(struct Map_info *)
Check if vector map is 3D.
#define GV_LINE
Definition: dig_defines.h:184
#define GV_POINT
Feature types used in memory on run time (may change)
Definition: dig_defines.h:183
#define GV_BOUNDARY
Definition: dig_defines.h:185
#define GV_FACE
Definition: dig_defines.h:187
#define GV_KERNEL
Definition: dig_defines.h:188
const struct driver * driver
Definition: driver/init.c:25
#define TRUE
Definition: gis.h:78
#define _(str)
Definition: glocale.h:10
Data structure used for building pseudo-topology.
Definition: dig_structs.h:388
int * array
Offset list.
Definition: dig_structs.h:436
int array_alloc
Space allocated for offset list.
Definition: dig_structs.h:444
int array_num
Number of items in offset list.
Definition: dig_structs.h:440
Non-native format info (OGR)
Definition: dig_structs.h:505
char * dsn
OGR datasource name.
Definition: dig_structs.h:513
char * driver_name
OGR driver name.
Definition: dig_structs.h:509
OGRDataSourceH ds
Pointer to OGRDataSource.
Definition: dig_structs.h:530
char * layer_name
OGR layer name.
Definition: dig_structs.h:517
dbDriver * dbdriver
Open DB driver when writing attributes.
Definition: dig_structs.h:547
OGRLayerH layer
Pointer to OGRLayer.
Definition: dig_structs.h:534
char ** layer_options
Array of OGR layer options.
Definition: dig_structs.h:556
struct Format_info_offset offset
Offset list used for building pseudo-topology.
Definition: dig_structs.h:577
struct Format_info_ogr ogr
OGR info.
Definition: dig_structs.h:708
Definition: gis.h:528
Vector map info.
Definition: dig_structs.h:1243
struct Format_info fInfo
Format info for non-native formats.
Definition: dig_structs.h:1400
Definition: driver.h:27
Layer (old: field) information.
Definition: dig_structs.h:131
char * table
Name of DB table.
Definition: dig_structs.h:151
char * driver
Name of DB driver ('sqlite', 'dbf', ...)
Definition: dig_structs.h:143
char * database
Definition: dig_structs.h:147
char * key
Name of key column (usually 'cat')
Definition: dig_structs.h:155
int number
Layer number.
Definition: dig_structs.h:135
Feature category info.
Definition: dig_structs.h:1677
int * field
Array of layers (fields)
Definition: dig_structs.h:1681
int n_cats
Number of categories attached to element.
Definition: dig_structs.h:1689
Feature geometry info - coordinates.
Definition: dig_structs.h:1651
double * y
Array of Y coordinates.
Definition: dig_structs.h:1659
double * x
Array of X coordinates.
Definition: dig_structs.h:1655
int n_points
Number of points.
Definition: dig_structs.h:1667
double * z
Array of Z coordinates.
Definition: dig_structs.h:1663
int V1_delete_line_ogr(struct Map_info *Map, off_t offset)
Deletes feature at the given offset on level 1 (OGR interface)
Definition: write_ogr.c:119
off_t V2__write_area_ogr(struct Map_info *Map, const struct line_pnts **points, int nparts, const struct line_cats *cats)
Writes area on topological level (OGR Simple Features interface, internal use only)
Definition: write_ogr.c:164
off_t V1_write_line_ogr(struct Map_info *Map, int type, const struct line_pnts *points, const struct line_cats *cats)
Writes feature on level 1 (OGR interface)
Definition: write_ogr.c:63
off_t V1_rewrite_line_ogr(struct Map_info *Map, off_t offset, int type, const struct line_pnts *points, const struct line_cats *cats)
Rewrites feature at the given offset on level 1 (OGR interface)
Definition: write_ogr.c:89