write_ogr.c 19 KB

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