open_ogr.c 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486
  1. /*!
  2. \file lib/vector/Vlib/open_ogr.c
  3. \brief Vector library - Open OGR layer as vector map layer
  4. Higher level functions for reading/writing/manipulating vectors.
  5. (C) 2001-2010 by the GRASS Development Team
  6. This program is free software under the GNU General Public License
  7. (>=v2). Read the file COPYING that comes with GRASS for details.
  8. \author Original author CERL, probably Dave Gerdes or Mike Higgins.
  9. \author Update to GRASS 5.7 Radim Blazek and David D. Gray.
  10. \author Update to GRASS 7.0 Martin Landa <landa.martin gmail.com> (2009)
  11. */
  12. #include <unistd.h>
  13. #include <string.h>
  14. #include <sys/types.h>
  15. #include <sys/stat.h>
  16. #include <grass/vector.h>
  17. #include <grass/dbmi.h>
  18. #include <grass/gprojects.h>
  19. #include <grass/glocale.h>
  20. #ifdef HAVE_OGR
  21. #include <ogr_api.h>
  22. #include <cpl_string.h>
  23. static int sqltype_to_ogrtype(int);
  24. static int create_table(OGRLayerH, const struct field_info *);
  25. /*!
  26. \brief Open existing OGR layer (level 1 - without feature index file)
  27. Map->name, Map->mapset, Map->fInfo.ogr.dsn and
  28. Map->fInfo.ogr.layer_name must be set before.
  29. \param[in,out] Map pointer to Map_info structure
  30. \param update TRUE for write mode, otherwise read-only
  31. \return 0 success
  32. \return -1 error
  33. */
  34. int V1_open_old_ogr(struct Map_info *Map, int update)
  35. {
  36. int i, layer, nLayers;
  37. OGRDataSourceH Ogr_ds;
  38. OGRLayerH Ogr_layer;
  39. OGRFeatureDefnH Ogr_featuredefn;
  40. OGRwkbGeometryType Ogr_geom_type;
  41. Ogr_layer = NULL;
  42. Ogr_geom_type = wkbUnknown;
  43. if (!Map->fInfo.ogr.dsn) {
  44. G_fatal_error(_("OGR datasource not defined"));
  45. return -1;
  46. }
  47. if (!Map->fInfo.ogr.layer_name) {
  48. G_fatal_error(_("OGR layer not defined"));
  49. return -1;
  50. }
  51. G_debug(2, "V1_open_old_ogr(): dsn = %s layer = %s", Map->fInfo.ogr.dsn,
  52. Map->fInfo.ogr.layer_name);
  53. OGRRegisterAll();
  54. /* open data source handle */
  55. Ogr_ds = OGROpen(Map->fInfo.ogr.dsn, FALSE, NULL);
  56. if (Ogr_ds == NULL)
  57. G_fatal_error(_("Unable to open OGR data source '%s'"),
  58. Map->fInfo.ogr.dsn);
  59. Map->fInfo.ogr.ds = Ogr_ds;
  60. /* get layer number */
  61. layer = -1;
  62. nLayers = OGR_DS_GetLayerCount(Ogr_ds);
  63. G_debug(2, "%d layers found in data source", nLayers);
  64. for (i = 0; i < nLayers; i++) {
  65. Ogr_layer = OGR_DS_GetLayer(Ogr_ds, i);
  66. Ogr_featuredefn = OGR_L_GetLayerDefn(Ogr_layer);
  67. if (strcmp(OGR_FD_GetName(Ogr_featuredefn), Map->fInfo.ogr.layer_name) == 0) {
  68. Ogr_geom_type = OGR_FD_GetGeomType(Ogr_featuredefn);
  69. layer = i;
  70. break;
  71. }
  72. }
  73. if (layer == -1) {
  74. OGR_DS_Destroy(Ogr_ds);
  75. G_fatal_error(_("OGR layer <%s> not found"),
  76. Map->fInfo.ogr.layer_name);
  77. }
  78. G_debug(2, "OGR layer %d opened", layer);
  79. Map->fInfo.ogr.layer = Ogr_layer;
  80. if (update && OGR_L_TestCapability(Map->fInfo.ogr.layer, OLCTransactions))
  81. OGR_L_StartTransaction(Map->fInfo.ogr.layer);
  82. Map->fInfo.ogr.lines = NULL;
  83. Map->fInfo.ogr.lines_types = NULL;
  84. Map->fInfo.ogr.lines_alloc = 0;
  85. Map->fInfo.ogr.lines_num = 0;
  86. Map->fInfo.ogr.lines_next = 0;
  87. switch(Ogr_geom_type) {
  88. case wkbPoint25D: case wkbLineString25D: case wkbPolygon25D:
  89. case wkbMultiPoint25D: case wkbMultiLineString25D: case wkbMultiPolygon25D:
  90. case wkbGeometryCollection25D:
  91. Map->head.with_z = WITH_Z;
  92. break;
  93. default:
  94. Map->head.with_z = WITHOUT_Z;
  95. break;
  96. }
  97. Map->fInfo.ogr.feature_cache = NULL;
  98. Map->fInfo.ogr.feature_cache_id = -1; /* FID >= 0 */
  99. return 0;
  100. }
  101. /*!
  102. \brief Open existing OGR layer (level 2 - feature index)
  103. \param[in,out] Map pointer to Map_info structure
  104. \return 0 success
  105. \return -1 error
  106. */
  107. int V2_open_old_ogr(struct Map_info *Map)
  108. {
  109. char elem[GPATH_MAX];
  110. char buf[5]; /* used for format version */
  111. long length;
  112. struct gvfile fp;
  113. struct Port_info port;
  114. int Version_Major, Version_Minor, Back_Major, Back_Minor, byte_order;
  115. G_debug(3, "V2_open_old_ogr()");
  116. sprintf(elem, "%s/%s", GV_DIRECTORY, Map->name);
  117. dig_file_init(&fp);
  118. fp.file = G_fopen_old(elem, GV_FIDX_ELEMENT, Map->mapset);
  119. if (fp.file == NULL) {
  120. G_warning(_("Unable to open fidx file for vector map <%s@%s>"),
  121. Map->name, Map->mapset);
  122. return -1;
  123. }
  124. /* Header */
  125. if (0 >= dig__fread_port_C(buf, 5, &fp))
  126. return (-1);
  127. Version_Major = buf[0];
  128. Version_Minor = buf[1];
  129. Back_Major = buf[2];
  130. Back_Minor = buf[3];
  131. byte_order = buf[4];
  132. /* check version numbers */
  133. if (Version_Major > 5 || Version_Minor > 0) {
  134. if (Back_Major > 5 || Back_Minor > 0) {
  135. G_fatal_error(_("Feature index format version %d.%d is not supported by this release."
  136. " Try to rebuild topology or upgrade GRASS."),
  137. Version_Major, Version_Minor);
  138. return (-1);
  139. }
  140. G_warning(_("Your GRASS version does not fully support feature index format %d.%d of the vector."
  141. " Consider to rebuild topology or upgrade GRASS."),
  142. Version_Major, Version_Minor);
  143. }
  144. dig_init_portable(&port, byte_order);
  145. dig_set_cur_port(&port);
  146. /* Body */
  147. /* bytes 6 - 9 : header size */
  148. if (0 >= dig__fread_port_L(&length, 1, &fp))
  149. return (-1);
  150. G_debug(3, " header size %ld", length);
  151. G_fseek(fp.file, length, SEEK_SET);
  152. /* number of records */
  153. if (0 >= dig__fread_port_I(&(Map->fInfo.ogr.offset_num), 1, &fp))
  154. return (-1);
  155. /* alloc space */
  156. Map->fInfo.ogr.offset =
  157. (int *)G_malloc(Map->fInfo.ogr.offset_num * sizeof(int));
  158. Map->fInfo.ogr.offset_alloc = Map->fInfo.ogr.offset_num;
  159. /* offsets */
  160. if (0 >= dig__fread_port_I(Map->fInfo.ogr.offset,
  161. Map->fInfo.ogr.offset_num, &fp))
  162. return (-1);
  163. fclose(fp.file);
  164. G_debug(3, "%d records read from fidx", Map->fInfo.ogr.offset_num);
  165. Map->fInfo.ogr.next_line = 1;
  166. return 0;
  167. }
  168. /*!
  169. \brief Prepare OGR datasource for creating new OGR layer (level 1)
  170. New OGR layer can be created by V2_open_new_ogr().
  171. \param[out] Map pointer to Map_info structure
  172. \param name name of OGR layer to create
  173. \param with_z WITH_Z for 3D vector data otherwise WITHOUT_Z
  174. \return 0 success
  175. \return -1 error
  176. */
  177. int V1_open_new_ogr(struct Map_info *Map, const char *name, int with_z)
  178. {
  179. OGRSFDriverH Ogr_driver;
  180. OGRDataSourceH Ogr_ds;
  181. OGRLayerH Ogr_layer;
  182. OGRFeatureDefnH Ogr_featuredefn;
  183. int i, nlayers;
  184. char **Ogr_layer_options;
  185. Ogr_layer_options = NULL;
  186. OGRRegisterAll();
  187. Ogr_driver = OGRGetDriverByName(Map->fInfo.ogr.driver_name);
  188. if (!Ogr_driver) {
  189. G_warning(_("Unable to get OGR driver <%s>"), Map->fInfo.ogr.driver_name);
  190. return -1;
  191. }
  192. Map->fInfo.ogr.driver = Ogr_driver;
  193. /* TODO: creation options */
  194. Ogr_ds = OGR_Dr_CreateDataSource(Ogr_driver, Map->fInfo.ogr.dsn, NULL);
  195. if (!Ogr_ds) {
  196. G_warning(_("Unable to create OGR data source '%s'"),
  197. Map->fInfo.ogr.dsn);
  198. return -1;
  199. }
  200. Map->fInfo.ogr.ds = Ogr_ds;
  201. nlayers = OGR_DS_GetLayerCount(Ogr_ds);
  202. for (i = 0; i < nlayers; i++) {
  203. Ogr_layer = OGR_DS_GetLayer(Ogr_ds, i);
  204. Ogr_featuredefn = OGR_L_GetLayerDefn(Ogr_layer);
  205. if (strcmp(OGR_FD_GetName(Ogr_featuredefn), name) == 0) {
  206. if (G_get_overwrite()) {
  207. G_warning(_("OGR layer <%s> already exists and will be overwritten"),
  208. Map->fInfo.ogr.layer_name);
  209. if (OGR_DS_DeleteLayer(Ogr_ds, i) != OGRERR_NONE) {
  210. G_warning(_("Unable to delete OGR layer <%s>"),
  211. Map->fInfo.ogr.layer_name);
  212. return -1;
  213. }
  214. }
  215. else {
  216. G_fatal_error(_("OGR layer <%s> already exists in datasource '%s'"),
  217. Map->fInfo.ogr.layer_name, Map->fInfo.ogr.dsn);
  218. }
  219. Map->fInfo.ogr.layer = NULL;
  220. break;
  221. }
  222. }
  223. return 0;
  224. }
  225. /*!
  226. \brief Create new OGR layer in given OGR datasource (level 2)
  227. V1_open_new_ogr() is required to be called before this function.
  228. List of currently supported types:
  229. - GV_POINT (wkbPoint)
  230. - GV_LINE (wkbLineString)
  231. - GV_BOUNDARY (wkb_Polygon)
  232. \param[in,out] Map pointer to Map_info structure
  233. \param type feature type (GV_POINT, GV_LINE, ...)
  234. \return 0 success
  235. \return -1 error
  236. */
  237. int V2_open_new_ogr(struct Map_info *Map, int type)
  238. {
  239. int ndblinks;
  240. OGRLayerH Ogr_layer;
  241. OGRSpatialReferenceH Ogr_spatial_ref;
  242. struct field_info *Fi;
  243. struct Key_Value *projinfo, *projunits;
  244. OGRwkbGeometryType Ogr_geom_type;
  245. char **Ogr_layer_options;
  246. if (!Map->fInfo.ogr.driver_name ||
  247. !Map->fInfo.ogr.layer_name ||
  248. !Map->fInfo.ogr.ds)
  249. return -1;
  250. /* get spatial reference */
  251. projinfo = G_get_projinfo();
  252. projunits = G_get_projunits();
  253. Ogr_spatial_ref = GPJ_grass_to_osr(projinfo, projunits);
  254. switch(type) {
  255. case GV_POINT:
  256. Ogr_geom_type = wkbPoint;
  257. break;
  258. case GV_LINE:
  259. Ogr_geom_type = wkbLineString;
  260. break;
  261. case GV_BOUNDARY:
  262. Ogr_geom_type = wkbPolygon;
  263. break;
  264. default:
  265. G_warning(_("Unsupported geometry type (%d)"), type);
  266. return -1;
  267. }
  268. Ogr_layer_options = Map->fInfo.ogr.layer_options;
  269. if (Vect_is_3d(Map)) {
  270. if (strcmp(Map->fInfo.ogr.driver_name, "PostgreSQL") == 0) {
  271. Ogr_layer_options = CSLSetNameValue(Ogr_layer_options, "DIM", "3");
  272. }
  273. }
  274. else {
  275. if (strcmp(Map->fInfo.ogr.driver_name, "PostgreSQL") == 0) {
  276. Ogr_layer_options = CSLSetNameValue(Ogr_layer_options, "DIM", "2");
  277. }
  278. }
  279. Ogr_layer = OGR_DS_CreateLayer(Map->fInfo.ogr.ds, Map->fInfo.ogr.layer_name,
  280. Ogr_spatial_ref, Ogr_geom_type, Ogr_layer_options);
  281. CSLDestroy(Ogr_layer_options);
  282. if (!Ogr_layer) {
  283. G_warning(_("Unable to create OGR layer <%s> in '%s'"),
  284. Map->fInfo.ogr.layer_name, Map->fInfo.ogr.dsn);
  285. return -1;
  286. }
  287. Map->fInfo.ogr.layer = Ogr_layer;
  288. ndblinks = Vect_get_num_dblinks(Map);
  289. if (ndblinks > 0) {
  290. /* write also attributes */
  291. Fi = Vect_get_dblink(Map, 0);
  292. if (Fi) {
  293. if (ndblinks > 1)
  294. G_warning(_("More layers defined, using driver <%s> and "
  295. "database <%s>"), Fi->driver, Fi->database);
  296. create_table(Map->fInfo.ogr.layer, Fi);
  297. G_free(Fi);
  298. }
  299. else
  300. G_warning(_("Database connection not defined. "
  301. "Unable to write attributes."));
  302. }
  303. if (OGR_L_TestCapability(Map->fInfo.ogr.layer, OLCTransactions))
  304. OGR_L_StartTransaction(Map->fInfo.ogr.layer);
  305. return 0;
  306. }
  307. int create_table(OGRLayerH hLayer, const struct field_info *Fi)
  308. {
  309. int col, ncols;
  310. int sqltype, ogrtype, length;
  311. const char *colname;
  312. dbDriver *driver;
  313. dbHandle handle;
  314. dbCursor cursor;
  315. dbTable *table;
  316. dbColumn *column;
  317. dbString sql;
  318. OGRFieldDefnH hFieldDefn;
  319. OGRFeatureDefnH hFeatureDefn;
  320. db_init_string(&sql);
  321. db_init_handle(&handle);
  322. driver = db_start_driver(Fi->driver);
  323. if (!driver) {
  324. G_warning(_("Unable to start driver <%s>"), Fi->driver);
  325. return -1;
  326. }
  327. db_set_handle(&handle, Fi->database, NULL);
  328. if (db_open_database(driver, &handle) != DB_OK) {
  329. G_warning(_("Unable to open database <%s> by driver <%s>"),
  330. Fi->database, Fi->driver);
  331. db_close_database_shutdown_driver(driver);
  332. return -1;
  333. }
  334. /* to get no data */
  335. db_set_string(&sql, "select * from ");
  336. db_append_string(&sql, Fi->table);
  337. db_append_string(&sql, " where 0 = 1");
  338. if (db_open_select_cursor(driver, &sql, &cursor, DB_SEQUENTIAL) !=
  339. DB_OK) {
  340. G_warning(_("Unable to open select cursor: '%s'"),
  341. db_get_string(&sql));
  342. db_close_database_shutdown_driver(driver);
  343. return -1;
  344. }
  345. table = db_get_cursor_table(&cursor);
  346. ncols = db_get_table_number_of_columns(table);
  347. hFeatureDefn = OGR_L_GetLayerDefn(hLayer);
  348. for (col = 0; col < ncols; col++) {
  349. column = db_get_table_column(table, col);
  350. colname = db_get_column_name(column);
  351. sqltype = db_get_column_sqltype(column);
  352. ogrtype = sqltype_to_ogrtype(sqltype);
  353. length = db_get_column_length(column);
  354. if (strcmp(OGR_L_GetFIDColumn(hLayer), colname) == 0 ||
  355. OGR_FD_GetFieldIndex(hFeatureDefn, colname) > -1) {
  356. /* field already exists */
  357. continue;
  358. }
  359. hFieldDefn = OGR_Fld_Create(colname, ogrtype);
  360. /* GDAL 1.9.0 (r22968) uses VARCHAR instead of CHAR */
  361. if (ogrtype == OFTString && length > 0)
  362. OGR_Fld_SetWidth(hFieldDefn, length);
  363. if (OGR_L_CreateField(hLayer, hFieldDefn, TRUE) != OGRERR_NONE) {
  364. G_warning(_("Creating field <%s> failed"), colname);
  365. db_close_database_shutdown_driver(driver);
  366. return -1;
  367. }
  368. OGR_Fld_Destroy(hFieldDefn);
  369. }
  370. db_close_database_shutdown_driver(driver);
  371. return 0;
  372. }
  373. int sqltype_to_ogrtype(int sqltype)
  374. {
  375. int ctype, ogrtype;
  376. ctype = db_sqltype_to_Ctype(sqltype);
  377. switch(ctype) {
  378. case DB_C_TYPE_INT:
  379. ogrtype = OFTInteger;
  380. break;
  381. case DB_C_TYPE_DOUBLE:
  382. ogrtype = OFTReal;
  383. break;
  384. case DB_C_TYPE_STRING:
  385. ogrtype = OFTString;
  386. break;
  387. case DB_C_TYPE_DATETIME:
  388. ogrtype = OFTString;
  389. break;
  390. default:
  391. ogrtype = OFTString;
  392. break;
  393. }
  394. return ogrtype;
  395. }
  396. #endif