GRASS GIS 8 Programmer's Manual  8.5.0dev(2024)-d6dec75dd4
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  sprintf(buf, "SELECT * FROM %s WHERE %s = %d", Fi->table, Fi->key, cat);
575  G_debug(4, "SQL: %s", buf);
576  db_set_string(&dbstring, buf);
577 
578  /* select data */
579  if (db_open_select_cursor(driver, &dbstring, &cursor, DB_SEQUENTIAL) !=
580  DB_OK) {
581  G_warning(_("Unable to select attributes for category %d"), cat);
582  return -1;
583  }
584 
585  if (db_fetch(&cursor, DB_NEXT, &more) != DB_OK) {
586  G_warning(_("Unable to fetch data from table <%s>"), Fi->table);
587  return -1;
588  }
589 
590  if (!more) {
591  G_warning(_("No database record for category %d, "
592  "no attributes will be written"),
593  cat);
594  return -1;
595  }
596 
597  fidcol = OGR_L_GetFIDColumn(Ogr_layer);
598 
599  table = db_get_cursor_table(&cursor);
600  ncol = db_get_table_number_of_columns(table);
601  for (j = 0; j < ncol; j++) {
602  column = db_get_table_column(table, j);
603  colname = db_get_column_name(column);
604  if (fidcol && *fidcol && strcmp(colname, fidcol) == 0) {
605  /* skip fid column */
606  continue;
607  }
608  value = db_get_column_value(column);
609  /* for debug only */
610  db_convert_column_value_to_string(column, &dbstring);
611  G_debug(3, "col %d : val = %s", j, db_get_string(&dbstring));
612 
613  sqltype = db_get_column_sqltype(column);
614  ctype = db_sqltype_to_Ctype(sqltype);
615  ogrtype = sqltype_to_ogrtype(sqltype);
616  G_debug(3, " colctype = %d", ctype);
617 
618  ogrfieldnum = OGR_F_GetFieldIndex(Ogr_feature, colname);
619  if (ogrfieldnum < 0) {
620  /* create field if not exists */
621  hFieldDefn = OGR_Fld_Create(colname, ogrtype);
622  if (OGR_L_CreateField(Ogr_layer, hFieldDefn, TRUE) != OGRERR_NONE)
623  G_warning(_("Unable to create field <%s>"), colname);
624  ogrfieldnum = OGR_F_GetFieldIndex(Ogr_feature, colname);
625  }
626 
627  /* Reset */
628  OGR_F_UnsetField(Ogr_feature, ogrfieldnum);
629 
630  /* prevent writing NULL values */
631  if (!db_test_value_isnull(value)) {
632  switch (ctype) {
633  case DB_C_TYPE_INT:
634  OGR_F_SetFieldInteger(Ogr_feature, ogrfieldnum,
635  db_get_value_int(value));
636  break;
637  case DB_C_TYPE_DOUBLE:
638  OGR_F_SetFieldDouble(Ogr_feature, ogrfieldnum,
639  db_get_value_double(value));
640  break;
641  case DB_C_TYPE_STRING:
642  OGR_F_SetFieldString(Ogr_feature, ogrfieldnum,
643  db_get_value_string(value));
644  break;
645  case DB_C_TYPE_DATETIME:
646  db_convert_column_value_to_string(column, &dbstring);
647  OGR_F_SetFieldString(Ogr_feature, ogrfieldnum,
648  db_get_string(&dbstring));
649  break;
650  default:
651  G_warning(_("Unsupported column type %d"), ctype);
652  break;
653  }
654  }
655  }
656 
657  db_close_cursor(&cursor);
658 
659  db_free_string(&dbstring);
660 
661  return 1;
662 }
663 
664 int sqltype_to_ogrtype(int sqltype)
665 {
666  int ctype, ogrtype;
667 
668  ctype = db_sqltype_to_Ctype(sqltype);
669 
670  switch (ctype) {
671  case DB_C_TYPE_INT:
672  ogrtype = OFTInteger;
673  break;
674  case DB_C_TYPE_DOUBLE:
675  ogrtype = OFTReal;
676  break;
677  case DB_C_TYPE_STRING:
678  ogrtype = OFTString;
679  break;
680  case DB_C_TYPE_DATETIME:
681  ogrtype = OFTString;
682  break;
683  default:
684  ogrtype = OFTString;
685  break;
686  }
687 
688  return ogrtype;
689 }
690 
691 #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:79
#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:21
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