GRASS GIS 7 Programmer's Manual  7.5.svn(2018)-r72636
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
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 <grass/vector.h>
21 #include <grass/dbmi.h>
22 #include <grass/gprojects.h>
23 #include <grass/glocale.h>
24 
25 #ifdef HAVE_OGR
26 #include <ogr_api.h>
27 #include <cpl_string.h>
28 
29 static dbDriver *create_table(OGRLayerH, const struct field_info *);
30 static int create_ogr_layer(struct Map_info *, int);
31 static off_t write_feature(struct Map_info *, int, const struct line_pnts **, int,
32  const struct line_cats *);
33 static int write_attributes(dbDriver *, int, const struct field_info *,
34  OGRLayerH, OGRFeatureH);
35 static int sqltype_to_ogrtype(int);
36 #endif
37 
38 /*!
39  \brief Writes feature on level 1 (OGR interface)
40 
41  Note:
42  - centroids are not supported in OGR, pseudotopo holds virtual
43  centroids (it's coordinates determined from spatial index)
44  - unclosed boundaries are not supported in OGR, pseudotopo treats
45  polygons as boundaries
46 
47  Supported feature types:
48  - GV_POINT (written as wkbPoint)
49  - GV_LINE (wkbLineString)
50  - GV_BOUNDARY (wkbPolygon)
51  - GV_FACE (wkbPolygon25D)
52  - GV_KERNEL (wkbPoint25D)
53 
54  \param Map pointer to Map_info structure
55  \param type feature type
56  \param points pointer to line_pnts structure (feature geometry)
57  \param cats pointer to line_cats structure (feature categories)
58 
59  \return feature index in offset array (related to pseudo-topology)
60  \return -1 on error
61 */
62 off_t V1_write_line_ogr(struct Map_info *Map, int type,
63  const struct line_pnts *points,
64  const struct line_cats *cats)
65 {
66 #ifdef HAVE_OGR
67  return write_feature(Map, type, &points, 1, cats);
68 #else
69  G_fatal_error(_("GRASS is not compiled with OGR support"));
70  return -1;
71 #endif
72 }
73 
74 /*!
75  \brief Rewrites feature at the given offset on level 1 (OGR interface)
76 
77  This function simply calls V1_delete_line_ogr() and V1_write_line_ogr().
78 
79  \param Map pointer to Map_info structure
80  \param offset feature offset
81  \param type feature type (see V1_write_line_ogr() for supported types)
82  \param points pointer to line_pnts structure (feature geometry)
83  \param cats pointer to line_cats structure (feature categories)
84 
85  \return feature offset (rewritten feature)
86  \return -1 on error
87 */
88 off_t V1_rewrite_line_ogr(struct Map_info *Map,
89  off_t offset, int type,
90  const struct line_pnts *points, const struct line_cats *cats)
91 {
92  G_debug(3, "V1_rewrite_line_ogr(): type=%d offset=%"PRI_OFF_T,
93  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 (%ld)"), offset);
135  return -1;
136  }
137 
138  if (OGR_L_DeleteFeature(ogr_info->layer,
139  ogr_info->offset.array[offset]) != 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,
165  const struct line_pnts **points, int nparts,
166  const struct line_cats *cats)
167 {
168  return write_feature(Map, GV_BOUNDARY, points, nparts, cats);
169 }
170 
171 dbDriver *create_table(OGRLayerH hLayer, const struct field_info *Fi)
172 {
173  int col, ncols;
174  int sqltype, ogrtype, length;
175 
176  const char *colname;
177 
178  dbDriver *driver;
179  dbHandle handle;
180  dbCursor cursor;
181  dbTable *table;
182  dbColumn *column;
183  dbString sql;
184 
185  OGRFieldDefnH hFieldDefn;
186  OGRFeatureDefnH hFeatureDefn;
187 
188  db_init_string(&sql);
189  db_init_handle(&handle);
190 
191  driver = db_start_driver(Fi->driver);
192  if (!driver) {
193  G_warning(_("Unable to start driver <%s>"), Fi->driver);
194  return NULL;
195  }
196  db_set_handle(&handle, Fi->database, NULL);
197  if (db_open_database(driver, &handle) != DB_OK) {
198  G_warning(_("Unable to open database <%s> by driver <%s>"),
199  Fi->database, Fi->driver);
201  return NULL;
202  }
203 
204  /* to get no data */
205  db_set_string(&sql, "select * from ");
206  db_append_string(&sql, Fi->table);
207  db_append_string(&sql, " where 0 = 1");
208 
209  if (db_open_select_cursor(driver, &sql, &cursor, DB_SEQUENTIAL) !=
210  DB_OK) {
211  G_warning(_("Unable to open select cursor: '%s'"),
212  db_get_string(&sql));
214  return NULL;
215  }
216 
217  table = db_get_cursor_table(&cursor);
218  ncols = db_get_table_number_of_columns(table);
219 
220  hFeatureDefn = OGR_L_GetLayerDefn(hLayer);
221 
222  for (col = 0; col < ncols; col++) {
223  column = db_get_table_column(table, col);
224  colname = db_get_column_name(column);
225  sqltype = db_get_column_sqltype(column);
226  ogrtype = sqltype_to_ogrtype(sqltype);
227  length = db_get_column_length(column);
228 
229  if (strcmp(OGR_L_GetFIDColumn(hLayer), colname) == 0 ||
230  OGR_FD_GetFieldIndex(hFeatureDefn, colname) > -1) {
231  /* field already exists */
232  continue;
233  }
234 
235  hFieldDefn = OGR_Fld_Create(colname, ogrtype);
236  /* GDAL 1.9.0 (r22968) uses VARCHAR instead of CHAR */
237  if (ogrtype == OFTString && length > 0)
238  OGR_Fld_SetWidth(hFieldDefn, length);
239  if (OGR_L_CreateField(hLayer, hFieldDefn, TRUE) != OGRERR_NONE) {
240  G_warning(_("Creating field <%s> failed"), colname);
242  return NULL;
243  }
244 
245  OGR_Fld_Destroy(hFieldDefn);
246  }
247 
248  return driver;
249 }
250 
251 /*!
252  \brief Create new OGR layer in given OGR datasource (internal use only)
253 
254  V1_open_new_ogr() is required to be called before this function.
255 
256  List of currently supported types:
257  - GV_POINT (wkbPoint)
258  - GV_LINE (wkbLineString)
259  - GV_BOUNDARY (wkb_Polygon)
260  \param[in,out] Map pointer to Map_info structure
261  \param type feature type (GV_POINT, GV_LINE, ...)
262 
263  \return 0 success
264  \return -1 error
265 */
266 int create_ogr_layer(struct Map_info *Map, int type)
267 {
268  int ndblinks;
269  OGRLayerH Ogr_layer;
270  OGRSpatialReferenceH Ogr_spatial_ref;
271 
272  struct field_info *Fi;
273  struct Key_Value *projinfo, *projunits, *projepsg;
274  struct Format_info_ogr *ogr_info;
275 
276  OGRwkbGeometryType Ogr_geom_type;
277  char **Ogr_layer_options;
278 
279  ogr_info = &(Map->fInfo.ogr);
280 
281  if (!ogr_info->driver_name ||
282  !ogr_info->layer_name ||
283  !ogr_info->ds)
284  return -1;
285 
286  /* get spatial reference */
287  projinfo = G_get_projinfo();
288  projunits = G_get_projunits();
289  projepsg = G_get_projepsg();
290  Ogr_spatial_ref = GPJ_grass_to_osr2(projinfo, projunits, projepsg);
291  G_free_key_value(projinfo);
292  G_free_key_value(projunits);
293 
294  /* determine geometry type */
295  switch(type) {
296  case GV_POINT:
297  Ogr_geom_type = wkbPoint;
298  break;
299  case GV_LINE:
300  Ogr_geom_type = wkbLineString;
301  break;
302  case GV_BOUNDARY:
303  Ogr_geom_type = wkbPolygon;
304  break;
305  default:
306  G_warning(_("Unsupported geometry type (%d)"), type);
307  return -1;
308  }
309 
310  /* check creation options */
311  Ogr_layer_options = ogr_info->layer_options;
312  if (Vect_is_3d(Map)) {
313  if (strcmp(ogr_info->driver_name, "PostgreSQL") == 0) {
314  Ogr_layer_options = CSLSetNameValue(Ogr_layer_options, "DIM", "3");
315  }
316  }
317  else {
318  if (strcmp(ogr_info->driver_name, "PostgreSQL") == 0) {
319  Ogr_layer_options = CSLSetNameValue(Ogr_layer_options, "DIM", "2");
320  }
321  }
322 
323  /* create new OGR layer */
324  Ogr_layer = OGR_DS_CreateLayer(ogr_info->ds, ogr_info->layer_name,
325  Ogr_spatial_ref, Ogr_geom_type, Ogr_layer_options);
326  CSLDestroy(Ogr_layer_options);
327  if (!Ogr_layer) {
328  G_warning(_("Unable to create OGR layer <%s> in '%s'"),
329  ogr_info->layer_name, ogr_info->dsn);
330  return -1;
331  }
332  ogr_info->layer = Ogr_layer;
333 
334  ndblinks = Vect_get_num_dblinks(Map);
335  if (ndblinks > 0) {
336  /* write also attributes */
337  Fi = Vect_get_dblink(Map, 0);
338  if (Fi) {
339  if (ndblinks > 1)
340  G_warning(_("More layers defined, using driver <%s> and "
341  "database <%s>"), Fi->driver, Fi->database);
342  ogr_info->dbdriver = create_table(ogr_info->layer, Fi);
343  G_free(Fi);
344  }
345  else
346  G_warning(_("Database connection not defined. "
347  "Unable to write attributes."));
348  }
349 
350  if (OGR_L_TestCapability(ogr_info->layer, OLCTransactions))
351  OGR_L_StartTransaction(ogr_info->layer);
352 
353  return 0;
354 }
355 
356 /*!
357  \brief Write OGR feature
358 
359  \param Map pointer to Map_info structure
360  \param type feature type (GV_POINT, GV_LINE, ...)
361  \param bpoints feature geometry
362  \param cats feature categories
363  \param ipoints isle geometry for polygons on NULL
364  \param nisles number of isles
365 
366  \return feature offset into file
367  \return -1 on error
368 */
369 off_t write_feature(struct Map_info *Map, int type,
370  const struct line_pnts **p_points, int nparts,
371  const struct line_cats *cats)
372 {
373  int i, cat, ret;
374 
375  struct field_info *Fi;
376  const struct line_pnts *points;
377  struct Format_info_ogr *ogr_info;
378  struct Format_info_offset *offset_info;
379 
380  off_t offset;
381 
382  OGRGeometryH Ogr_geometry;
383  OGRFeatureH Ogr_feature;
384  OGRFeatureDefnH Ogr_featuredefn;
385  OGRwkbGeometryType Ogr_geom_type;
386 
387  ogr_info = &(Map->fInfo.ogr);
388  offset_info = &(ogr_info->offset);
389 
390  if (nparts < 1)
391  return -1;
392 
393  points = p_points[0]; /* feature geometry */
394 
395  if (!ogr_info->layer) {
396  /* create OGR layer if doesn't exist */
397  if (create_ogr_layer(Map, type) < 0)
398  return -1;
399  }
400 
401  if (!points)
402  return 0;
403 
404  cat = -1; /* no attributes to be written */
405  if (cats->n_cats > 0 && Vect_get_num_dblinks(Map) > 0) {
406  /* check for attributes */
407  Fi = Vect_get_dblink(Map, 0);
408  if (Fi) {
409  if (!Vect_cat_get(cats, Fi->number, &cat))
410  G_warning(_("No category defined for layer %d"), Fi->number);
411  if (cats->n_cats > 1) {
412  G_warning(_("Feature has more categories, using "
413  "category %d (from layer %d)"),
414  cat, cats->field[0]);
415  }
416  }
417  }
418 
419  Ogr_featuredefn = OGR_L_GetLayerDefn(ogr_info->layer);
420  Ogr_geom_type = OGR_FD_GetGeomType(Ogr_featuredefn);
421 
422  /* determine matching OGR feature geometry type */
423  if (type & (GV_POINT | GV_KERNEL)) {
424  if (Ogr_geom_type != wkbPoint &&
425  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,
501  cat, Fi, ogr_info->layer, 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(offset_info->array,
512  offset_info->array_alloc *
513  sizeof(int));
514  }
515 
516  offset = offset_info->array_num;
517 
518  offset_info->array[offset_info->array_num++] = (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,
575  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) != DB_OK) {
581  G_warning(_("Unable to select attributes for category %d"),
582  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>"),
588  Fi->table);
589  return -1;
590  }
591 
592  if (!more) {
593  G_warning(_("No database record for category %d, "
594  "no attributes will be written"),
595  cat);
596  return -1;
597  }
598 
599  fidcol = OGR_L_GetFIDColumn(Ogr_layer);
600 
601  table = db_get_cursor_table(&cursor);
602  ncol = db_get_table_number_of_columns(table);
603  for (j = 0; j < ncol; j++) {
604  column = db_get_table_column(table, j);
605  colname = db_get_column_name(column);
606  if (fidcol && *fidcol && strcmp(colname, fidcol) == 0) {
607  /* skip fid column */
608  continue;
609  }
610  value = db_get_column_value(column);
611  /* for debug only */
612  db_convert_column_value_to_string(column, &dbstring);
613  G_debug(3, "col %d : val = %s", j,
614  db_get_string(&dbstring));
615 
616  sqltype = db_get_column_sqltype(column);
617  ctype = db_sqltype_to_Ctype(sqltype);
618  ogrtype = sqltype_to_ogrtype(sqltype);
619  G_debug(3, " colctype = %d", ctype);
620 
621  ogrfieldnum = OGR_F_GetFieldIndex(Ogr_feature, colname);
622  if (ogrfieldnum < 0) {
623  /* create field if not exists */
624  hFieldDefn = OGR_Fld_Create(colname, ogrtype);
625  if (OGR_L_CreateField(Ogr_layer, hFieldDefn, TRUE) != OGRERR_NONE)
626  G_warning(_("Unable to create field <%s>"), colname);
627  ogrfieldnum = OGR_F_GetFieldIndex(Ogr_feature, colname);
628  }
629 
630  /* Reset */
631  OGR_F_UnsetField(Ogr_feature, ogrfieldnum);
632 
633  /* prevent writing NULL values */
634  if (!db_test_value_isnull(value)) {
635  switch (ctype) {
636  case DB_C_TYPE_INT:
637  OGR_F_SetFieldInteger(Ogr_feature, ogrfieldnum,
638  db_get_value_int(value));
639  break;
640  case DB_C_TYPE_DOUBLE:
641  OGR_F_SetFieldDouble(Ogr_feature, ogrfieldnum,
642  db_get_value_double(value));
643  break;
644  case DB_C_TYPE_STRING:
645  OGR_F_SetFieldString(Ogr_feature, ogrfieldnum,
646  db_get_value_string(value));
647  break;
648  case DB_C_TYPE_DATETIME:
650  &dbstring);
651  OGR_F_SetFieldString(Ogr_feature, ogrfieldnum,
652  db_get_string(&dbstring));
653  break;
654  default:
655  G_warning(_("Unsupported column type %d"), ctype);
656  break;
657  }
658  }
659  }
660 
661  db_close_cursor (&cursor);
662 
663  db_free_string(&dbstring);
664 
665  return 1;
666 }
667 
668 int sqltype_to_ogrtype(int sqltype)
669 {
670  int ctype, ogrtype;
671 
672  ctype = db_sqltype_to_Ctype(sqltype);
673 
674  switch(ctype) {
675  case DB_C_TYPE_INT:
676  ogrtype = OFTInteger;
677  break;
678  case DB_C_TYPE_DOUBLE:
679  ogrtype = OFTReal;
680  break;
681  case DB_C_TYPE_STRING:
682  ogrtype = OFTString;
683  break;
684  case DB_C_TYPE_DATETIME:
685  ogrtype = OFTString;
686  break;
687  default:
688  ogrtype = OFTString;
689  break;
690  }
691 
692  return ogrtype;
693 }
694 
695 #endif /* HAVE_OGR */
int * array
Offset list.
Definition: dig_structs.h:446
#define TRUE
Definition: gis.h:49
int db_test_value_isnull(dbValue *value)
Check of value is null.
Definition: value.c:26
int db_close_cursor(dbCursor *cursor)
Close cursor.
Definition: c_close_cur.c:27
struct driver * driver
Definition: driver/init.c:25
CELL cat
Definition: raster3d/cats.c:82
void G_free(void *buf)
Free allocated memory.
Definition: gis/alloc.c:149
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
const char * db_get_column_name(dbColumn *column)
Returns column name for given column.
struct Key_Value * G_get_projunits(void)
Gets units information for location.
Definition: get_projinfo.c:29
OGRDataSourceH ds
Pointer to OGRDataSource.
Definition: dig_structs.h:542
int db_close_database_shutdown_driver(dbDriver *driver)
Close driver/database connection.
Definition: db.c:62
struct Format_info_offset offset
Offset list used for building pseudo-topology.
Definition: dig_structs.h:589
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:88
int n_points
Number of points.
Definition: dig_structs.h:1692
char * table
Name of DB table.
Definition: dig_structs.h:155
#define DB_C_TYPE_DATETIME
Definition: dbmi.h:110
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
char * dsn
OGR datasource name.
Definition: dig_structs.h:525
int db_get_column_length(dbColumn *column)
Get column&#39;s length.
struct Format_info fInfo
Format info for non-native formats.
Definition: dig_structs.h:1415
#define PRI_OFF_T
Definition: gis.h:59
int Vect_get_num_dblinks(const struct Map_info *Map)
Get number of defined dblinks.
Definition: level_two.c:163
char ** layer_options
Array of OGR layer options.
Definition: dig_structs.h:568
#define NULL
Definition: ccmath.h:32
int V1_read_line_ogr(struct Map_info *Map, struct line_pnts *line_p, struct line_cats *line_c, off_t offset)
Read feature from OGR layer at given offset (level 1 without topology)
Definition: read_ogr.c:179
#define GV_POINT
Feature types used in memory on run time (may change)
Definition: dig_defines.h:182
char * db_get_string(const dbString *x)
Get string.
Definition: string.c:140
void G_free_key_value(struct Key_Value *kv)
Free allocated Key_Value structure.
Definition: key_value1.c:103
char * database
Definition: dig_structs.h:151
void G_fatal_error(const char *msg,...)
Print a fatal error message to stderr.
Definition: gis/error.c:160
int db_convert_column_value_to_string(dbColumn *column, dbString *string)
?
Definition: columnfmt.c:61
Feature category info.
Definition: dig_structs.h:1702
int db_append_string(dbString *x, const char *s)
Append string to dbString.
Definition: string.c:205
int db_sqltype_to_Ctype(int sqltype)
Get C data type based on given SQL data type.
Definition: sqlCtype.c:24
#define GV_LINE
Definition: dig_defines.h:183
int db_fetch(dbCursor *cursor, int position, int *more)
Fetch data from open cursor.
Definition: c_fetch.c:28
Layer (old: field) information.
Definition: dig_structs.h:134
double * x
Array of X coordinates.
Definition: dig_structs.h:1680
Feature geometry info - coordinates.
Definition: dig_structs.h:1675
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:62
double db_get_value_double(dbValue *value)
Get double precision value.
Definition: value.c:50
#define GV_FACE
Definition: dig_defines.h:186
int db_get_column_sqltype(dbColumn *column)
Returns column sqltype for column.
int Vect_is_3d(const struct Map_info *Map)
Check if vector map is 3D.
Data structure used for building pseudo-topology.
Definition: dig_structs.h:397
dbTable * db_get_cursor_table(dbCursor *cursor)
Get table allocated by cursor.
Definition: cursor.c:67
int db_get_table_number_of_columns(dbTable *table)
Return the number of columns of the table.
int Vect_cat_get(const struct line_cats *Cats, int field, int *cat)
Get first found category of given field.
#define DB_NEXT
Definition: dbmi.h:114
#define DB_C_TYPE_STRING
Definition: dbmi.h:107
int n_cats
Number of categories attached to element.
Definition: dig_structs.h:1715
int G_debug(int level, const char *msg,...)
Print debugging message.
Definition: debug.c:65
dbValue * db_get_column_value(dbColumn *column)
Returns column value for given column structure.
#define GV_BOUNDARY
Definition: dig_defines.h:184
Non-native format info (OGR)
Definition: dig_structs.h:516
OGRSpatialReferenceH GPJ_grass_to_osr2(const struct Key_Value *proj_info, const struct Key_Value *proj_units, const struct Key_Value *proj_epsg)
Converts a GRASS co-ordinate system to an OGRSpatialReferenceH object. EPSG code is preferred if avai...
Definition: convert.c:361
struct Format_info_ogr ogr
OGR info.
Definition: dig_structs.h:722
struct Key_Value * G_get_projinfo(void)
Gets projection information for location.
Definition: get_projinfo.c:58
#define DB_C_TYPE_INT
Definition: dbmi.h:108
int db_set_handle(dbHandle *handle, const char *dbName, const char *dbSchema)
Set handle (database and schema name)
Definition: handle.c:39
int array_num
Number of items in offset list.
Definition: dig_structs.h:450
Definition: gis.h:479
int array_alloc
Space allocated for offset list.
Definition: dig_structs.h:454
Vector map info.
Definition: dig_structs.h:1259
struct field_info * Vect_get_dblink(const struct Map_info *Map, int link)
Get information about link to database.
Definition: field.c:421
double * y
Array of Y coordinates.
Definition: dig_structs.h:1684
char * driver
Name of DB driver (&#39;sqlite&#39;, &#39;dbf&#39;, ...)
Definition: dig_structs.h:147
char * layer_name
OGR layer name.
Definition: dig_structs.h:529
struct Key_Value * G_get_projepsg(void)
Gets EPSG information for the current location.
Definition: get_projinfo.c:85
#define DB_SEQUENTIAL
Definition: dbmi.h:123
#define DB_C_TYPE_DOUBLE
Definition: dbmi.h:109
int number
Layer number.
Definition: dig_structs.h:139
void db_init_handle(dbHandle *handle)
Initialize handle (i.e database/schema)
Definition: handle.c:23
char * driver_name
OGR driver name.
Definition: dig_structs.h:521
dbDriver * dbdriver
Open DB driver when writing attributes.
Definition: dig_structs.h:559
int db_set_string(dbString *x, const char *s)
Inserts string to dbString (enlarge string)
Definition: string.c:41
double * z
Array of Z coordinates.
Definition: dig_structs.h:1688
#define _(str)
Definition: glocale.h:13
int db_get_value_int(dbValue *value)
Get integer value.
Definition: value.c:38
int * field
Array of layers (fields)
Definition: dig_structs.h:1707
OGRLayerH layer
Pointer to OGRLayer.
Definition: dig_structs.h:546
int
Reads the categories file for map name in mapset and stores the categories in the pcats structure...
int db_open_database(dbDriver *driver, dbHandle *handle)
Open database connection.
Definition: c_opendb.c:27
void db_free_string(dbString *x)
Free allocated space for dbString.
Definition: string.c:150
dbColumn * db_get_table_column(dbTable *table, int idx)
Returns column structure for given table and column number.
dbDriver * db_start_driver(const char *name)
Initialize a new dbDriver for db transaction.
Definition: start.c:50
const char * db_get_value_string(dbValue *value)
Get string value.
Definition: value.c:92
void G_warning(const char *msg,...)
Print a warning message to stderr.
Definition: gis/error.c:204
int db_open_select_cursor(dbDriver *driver, dbString *select, dbCursor *cursor, int mode)
Open select cursor.
Definition: c_openselect.c:37
void db_init_string(dbString *x)
Initialize dbString.
Definition: string.c:25
#define GV_KERNEL
Definition: dig_defines.h:187
#define DB_OK
Definition: dbmi.h:71
char * key
Name of key column (usually &#39;cat&#39;)
Definition: dig_structs.h:159