header_finfo.c 7.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281
  1. /*!
  2. \file lib/vector/Vlib/header_finfo.c
  3. \brief Vector library - header manipulation (relevant for external
  4. formats)
  5. Higher level functions for reading/writing/manipulating vectors.
  6. (C) 2001-2013 by the GRASS Development Team
  7. This program is free software under the GNU General Public License
  8. (>=v2). Read the file COPYING that comes with GRASS for details.
  9. \author Original author CERL, probably Dave Gerdes or Mike Higgins.
  10. \author Update to GRASS 5.7 Radim Blazek and David D. Gray.
  11. \author Update to GRASS 7 (OGR/PostGIS support) by Martin Landa <landa.martin gmail.com>
  12. */
  13. #include <string.h>
  14. #include <grass/vector.h>
  15. #include <grass/glocale.h>
  16. /*!
  17. \brief Get datasource name (relevant only for non-native formats)
  18. Returns:
  19. - datasource name for OGR format (GV_FORMAT_OGR and GV_FORMAT_OGR_DIRECT)
  20. - database name for PostGIS format (GV_FORMAT_POSTGIS)
  21. \param Map pointer to Map_info structure
  22. \return string containing OGR/PostGIS datasource name
  23. \return NULL on error (map format is native)
  24. */
  25. const char *Vect_get_finfo_dsn_name(const struct Map_info *Map)
  26. {
  27. if (Map->format == GV_FORMAT_OGR ||
  28. Map->format == GV_FORMAT_OGR_DIRECT) {
  29. #ifndef HAVE_OGR
  30. G_warning(_("GRASS is not compiled with OGR support"));
  31. #endif
  32. return Map->fInfo.ogr.dsn;
  33. }
  34. else if (Map->format == GV_FORMAT_POSTGIS) {
  35. #ifndef HAVE_POSTGRES
  36. G_warning(_("GRASS is not compiled with PostgreSQL support"));
  37. #endif
  38. return Map->fInfo.pg.db_name;
  39. }
  40. G_debug(1, "Native vector format detected for <%s>",
  41. Vect_get_full_name(Map));
  42. return NULL;
  43. }
  44. /*!
  45. \brief Get layer name (relevant only for non-native formats)
  46. Returns:
  47. - layer name for OGR format (GV_FORMAT_OGR and GV_FORMAT_OGR_DIRECT)
  48. - table name for PostGIS format (GV_FORMAT_POSTGIS) including schema (\<schema\>.\<table\>)
  49. Note: allocated string should be freed by G_free()
  50. \param Map pointer to Map_info structure
  51. \return string containing layer name
  52. \return NULL on error (map format is native)
  53. */
  54. char *Vect_get_finfo_layer_name(const struct Map_info *Map)
  55. {
  56. char *name;
  57. name = NULL;
  58. if (Map->format == GV_FORMAT_OGR ||
  59. Map->format == GV_FORMAT_OGR_DIRECT) {
  60. #ifndef HAVE_OGR
  61. G_warning(_("GRASS is not compiled with OGR support"));
  62. #endif
  63. name = G_store(Map->fInfo.ogr.layer_name);
  64. }
  65. else if (Map->format == GV_FORMAT_POSTGIS) {
  66. #ifndef HAVE_POSTGRES
  67. G_warning(_("GRASS is not compiled with PostgreSQL support"));
  68. #endif
  69. G_asprintf(&name, "%s.%s", Map->fInfo.pg.schema_name,
  70. Map->fInfo.pg.table_name);
  71. }
  72. else {
  73. G_debug(1, "Native vector format detected for <%s>",
  74. Vect_get_full_name(Map));
  75. }
  76. return name;
  77. }
  78. /*!
  79. \brief Get format info as string (relevant only for non-native formats)
  80. \param Map pointer to Map_info structure
  81. \return string containing name of OGR format
  82. \return "PostgreSQL" for PostGIS format (GV_FORMAT_POSTGIS)
  83. \return NULL on error (or on missing OGR/PostgreSQL support)
  84. */
  85. const char *Vect_get_finfo_format_info(const struct Map_info *Map)
  86. {
  87. if (Map->format == GV_FORMAT_OGR ||
  88. Map->format == GV_FORMAT_OGR_DIRECT) {
  89. #ifndef HAVE_OGR
  90. G_warning(_("GRASS is not compiled with OGR support"));
  91. #else
  92. if (!Map->fInfo.ogr.ds)
  93. return NULL;
  94. return OGR_Dr_GetName(OGR_DS_GetDriver(Map->fInfo.ogr.ds));
  95. #endif
  96. }
  97. else if (Map->format == GV_FORMAT_POSTGIS) {
  98. #ifndef HAVE_OGR
  99. G_warning(_("GRASS is not compiled with PostgreSQL support"));
  100. #else
  101. return "PostgreSQL";
  102. #endif
  103. }
  104. return NULL;
  105. }
  106. /*!
  107. \brief Get geometry type as string (relevant only for non-native formats)
  108. Note: All inner spaces are removed, function returns feature type in
  109. lowercase.
  110. \param Map pointer to Map_info structure
  111. \return allocated string containing geometry type info
  112. (point, linestring, polygon, ...)
  113. \return NULL on error (map format is native)
  114. */
  115. const char *Vect_get_finfo_geometry_type(const struct Map_info *Map)
  116. {
  117. int dim;
  118. char *ftype, *ftype_tmp;
  119. ftype_tmp = ftype = NULL;
  120. if (Map->format == GV_FORMAT_OGR ||
  121. Map->format == GV_FORMAT_OGR_DIRECT) {
  122. #ifndef HAVE_OGR
  123. G_warning(_("GRASS is not compiled with OGR support"));
  124. #else
  125. OGRwkbGeometryType Ogr_geom_type;
  126. OGRFeatureDefnH Ogr_feature_defn;
  127. if (!Map->fInfo.ogr.layer)
  128. return NULL;
  129. dim = -1;
  130. Ogr_feature_defn = OGR_L_GetLayerDefn(Map->fInfo.ogr.layer);
  131. Ogr_geom_type = wkbFlatten(OGR_FD_GetGeomType(Ogr_feature_defn));
  132. ftype_tmp = G_store(OGRGeometryTypeToName(Ogr_geom_type));
  133. #endif
  134. }
  135. else if (Map->format == GV_FORMAT_POSTGIS) {
  136. #ifndef HAVE_POSTGRES
  137. G_warning(_("GRASS is not compiled with PostgreSQL support"));
  138. #else
  139. char stmt[DB_SQL_MAX];
  140. const struct Format_info_pg *pg_info;
  141. PGresult *res;
  142. pg_info = &(Map->fInfo.pg);
  143. sprintf(stmt, "SELECT type,coord_dimension FROM geometry_columns "
  144. "WHERE f_table_schema = '%s' AND f_table_name = '%s'",
  145. pg_info->schema_name, pg_info->table_name);
  146. G_debug(2, "SQL: %s", stmt);
  147. res = PQexec(pg_info->conn, stmt);
  148. if (!res || PQresultStatus(res) != PGRES_TUPLES_OK ||
  149. PQntuples(res) != 1) {
  150. G_debug(1, "Unable to get feature type: %s",
  151. PQresultErrorMessage(res));
  152. return NULL;
  153. }
  154. ftype_tmp = G_store(PQgetvalue(res, 0, 0));
  155. dim = atoi(PQgetvalue(res, 0, 1));
  156. PQclear(res);
  157. #endif
  158. }
  159. if (!ftype_tmp)
  160. return NULL;
  161. ftype = G_str_replace(ftype_tmp, " ", "");
  162. G_free(ftype_tmp);
  163. ftype_tmp = NULL;
  164. G_str_to_lower(ftype);
  165. if (dim == 3) {
  166. ftype_tmp = (char *) G_malloc(3 + strlen(ftype) + 1);
  167. sprintf(ftype_tmp, "3D %s", ftype);
  168. G_free(ftype);
  169. ftype = ftype_tmp;
  170. }
  171. return ftype;
  172. }
  173. /*!
  174. \brief Get header info for non-native formats
  175. \param Map pointer to Map_info structure
  176. \return pointer to Format_info structure
  177. \return NULL for native format
  178. */
  179. const struct Format_info* Vect_get_finfo(const struct Map_info *Map)
  180. {
  181. /* do not check Map-format which is native (see
  182. * GRASS_VECTOR_EXTERNAL_IMMEDIATE) */
  183. if (Map->fInfo.ogr.driver_name || Map->fInfo.pg.conninfo)
  184. return &(Map->fInfo);
  185. return NULL;
  186. }
  187. /*!
  188. \brief Get topology type (relevant only for non-native formats)
  189. \param Map pointer to Map_info structure
  190. \param[out] toposchema Topology schema name or NULL
  191. \param[out] topogeom TopoGeometry column name or NULL
  192. \param[out] topo_geo_only TRUE for Topo-Geo data model or NULL
  193. \return GV_TOPO_NATIVE for native format
  194. \return GV_TOPO_PSEUDO for pseudo-topology
  195. \return GV_TOPO_POSTGIS for PostGIS Topology
  196. */
  197. int Vect_get_finfo_topology_info(const struct Map_info *Map,
  198. char **toposchema, char **topogeom, int* topo_geo_only)
  199. {
  200. if (Map->format == GV_FORMAT_OGR ||
  201. Map->format == GV_FORMAT_OGR_DIRECT) {
  202. #ifndef HAVE_OGR
  203. G_warning(_("GRASS is not compiled with OGR support"));
  204. #else
  205. return GV_TOPO_PSEUDO;
  206. #endif
  207. }
  208. if (Map->format == GV_FORMAT_POSTGIS) {
  209. const struct Format_info_pg *pg_info;
  210. pg_info = &(Map->fInfo.pg);
  211. if (pg_info->toposchema_name) {
  212. if (toposchema)
  213. *toposchema = G_store(pg_info->toposchema_name);
  214. if (topogeom)
  215. *topogeom = G_store(pg_info->topogeom_column);
  216. if (topo_geo_only)
  217. *topo_geo_only = pg_info->topo_geo_only;
  218. return GV_TOPO_POSTGIS;
  219. }
  220. else {
  221. return GV_TOPO_PSEUDO;
  222. }
  223. }
  224. return GV_TOPO_NATIVE;
  225. }