GRASS GIS 7 Programmer's Manual  7.9.dev(2021)-e5379bbd7
header_finfo.c
Go to the documentation of this file.
1 /*!
2  \file lib/vector/Vlib/header_finfo.c
3 
4  \brief Vector library - header manipulation (relevant for external
5  formats)
6 
7  Higher level functions for reading/writing/manipulating vectors.
8 
9  (C) 2001-2013 by the GRASS Development Team
10 
11  This program is free software under the GNU General Public License
12  (>=v2). Read the file COPYING that comes with GRASS for details.
13 
14  \author Original author CERL, probably Dave Gerdes or Mike Higgins.
15  \author Update to GRASS 5.7 Radim Blazek and David D. Gray.
16  \author Update to GRASS 7 (OGR/PostGIS support) by Martin Landa <landa.martin gmail.com>
17 */
18 
19 #include <string.h>
20 
21 #include <grass/vector.h>
22 #include <grass/glocale.h>
23 
24 /*!
25  \brief Get datasource name (relevant only for non-native formats)
26 
27  Returns:
28  - datasource name for OGR format (GV_FORMAT_OGR and GV_FORMAT_OGR_DIRECT)
29  - database name for PostGIS format (GV_FORMAT_POSTGIS)
30 
31  \param Map pointer to Map_info structure
32 
33  \return string containing OGR/PostGIS datasource name
34  \return NULL on error (map format is native)
35  */
36 const char *Vect_get_finfo_dsn_name(const struct Map_info *Map)
37 {
38  if (Map->format == GV_FORMAT_OGR ||
39  Map->format == GV_FORMAT_OGR_DIRECT) {
40 #ifndef HAVE_OGR
41  G_warning(_("GRASS is not compiled with OGR support"));
42 #endif
43  return Map->fInfo.ogr.dsn;
44  }
45  else if (Map->format == GV_FORMAT_POSTGIS) {
46 #ifndef HAVE_POSTGRES
47  G_warning(_("GRASS is not compiled with PostgreSQL support"));
48 #endif
49  return Map->fInfo.pg.db_name;
50  }
51 
52  G_debug(1, "Native vector format detected for <%s>",
53  Vect_get_full_name(Map));
54 
55  return NULL;
56 }
57 
58 /*!
59  \brief Get layer name (relevant only for non-native formats)
60 
61  Returns:
62  - layer name for OGR format (GV_FORMAT_OGR and GV_FORMAT_OGR_DIRECT)
63  - table name for PostGIS format (GV_FORMAT_POSTGIS) including schema (<schema>.<table>)
64 
65  Note: allocated string should be freed by G_free()
66 
67  \param Map pointer to Map_info structure
68 
69  \return string containing layer name
70  \return NULL on error (map format is native)
71  */
72 char *Vect_get_finfo_layer_name(const struct Map_info *Map)
73 {
74  char *name;
75 
76  name = NULL;
77  if (Map->format == GV_FORMAT_OGR ||
78  Map->format == GV_FORMAT_OGR_DIRECT) {
79 #ifndef HAVE_OGR
80  G_warning(_("GRASS is not compiled with OGR support"));
81 #endif
82  name = G_store(Map->fInfo.ogr.layer_name);
83  }
84  else if (Map->format == GV_FORMAT_POSTGIS) {
85 #ifndef HAVE_POSTGRES
86  G_warning(_("GRASS is not compiled with PostgreSQL support"));
87 #endif
88  G_asprintf(&name, "%s.%s", Map->fInfo.pg.schema_name,
89  Map->fInfo.pg.table_name);
90  }
91  else {
92  G_debug(1, "Native vector format detected for <%s>",
93  Vect_get_full_name(Map));
94  }
95 
96  return name;
97 }
98 
99 /*!
100  \brief Get format info as string (relevant only for non-native formats)
101 
102  \param Map pointer to Map_info structure
103 
104  \return string containing name of OGR format
105  \return "PostgreSQL" for PostGIS format (GV_FORMAT_POSTGIS)
106  \return NULL on error (or on missing OGR/PostgreSQL support)
107 */
108 const char *Vect_get_finfo_format_info(const struct Map_info *Map)
109 {
110  if (Map->format == GV_FORMAT_OGR ||
111  Map->format == GV_FORMAT_OGR_DIRECT) {
112 #ifndef HAVE_OGR
113  G_warning(_("GRASS is not compiled with OGR support"));
114 #else
115  if (!Map->fInfo.ogr.ds)
116  return NULL;
117 
118  return OGR_Dr_GetName(OGR_DS_GetDriver(Map->fInfo.ogr.ds));
119 #endif
120  }
121  else if (Map->format == GV_FORMAT_POSTGIS) {
122 #ifndef HAVE_OGR
123  G_warning(_("GRASS is not compiled with PostgreSQL support"));
124 #else
125  return "PostgreSQL";
126 #endif
127  }
128 
129  return NULL;
130 }
131 
132 /*!
133  \brief Get geometry type as string (relevant only for non-native formats)
134 
135  Note: All inner spaces are removed, function returns feature type in
136  lowercase.
137 
138  \param Map pointer to Map_info structure
139 
140  \return allocated string containing geometry type info
141  (point, linestring, polygon, ...)
142  \return NULL on error (map format is native)
143 */
144 const char *Vect_get_finfo_geometry_type(const struct Map_info *Map)
145 {
146  int dim;
147  char *ftype, *ftype_tmp;
148 
149  ftype_tmp = ftype = NULL;
150  if (Map->format == GV_FORMAT_OGR ||
151  Map->format == GV_FORMAT_OGR_DIRECT) {
152 #ifndef HAVE_OGR
153  G_warning(_("GRASS is not compiled with OGR support"));
154 #else
155  OGRwkbGeometryType Ogr_geom_type;
156  OGRFeatureDefnH Ogr_feature_defn;
157 
158  if (!Map->fInfo.ogr.layer)
159  return NULL;
160 
161  dim = -1;
162 
163  Ogr_feature_defn = OGR_L_GetLayerDefn(Map->fInfo.ogr.layer);
164  Ogr_geom_type = wkbFlatten(OGR_FD_GetGeomType(Ogr_feature_defn));
165 
166  ftype_tmp = G_store(OGRGeometryTypeToName(Ogr_geom_type));
167 #endif
168  }
169  else if (Map->format == GV_FORMAT_POSTGIS) {
170 #ifndef HAVE_POSTGRES
171  G_warning(_("GRASS is not compiled with PostgreSQL support"));
172 #else
173  char stmt[DB_SQL_MAX];
174 
175  const struct Format_info_pg *pg_info;
176 
177  PGresult *res;
178 
179  pg_info = &(Map->fInfo.pg);
180  sprintf(stmt, "SELECT type,coord_dimension FROM geometry_columns "
181  "WHERE f_table_schema = '%s' AND f_table_name = '%s'",
182  pg_info->schema_name, pg_info->table_name);
183  G_debug(2, "SQL: %s", stmt);
184 
185  res = PQexec(pg_info->conn, stmt);
186  if (!res || PQresultStatus(res) != PGRES_TUPLES_OK ||
187  PQntuples(res) != 1) {
188  G_debug(1, "Unable to get feature type: %s",
189  PQresultErrorMessage(res));
190  return NULL;
191  }
192  ftype_tmp = G_store(PQgetvalue(res, 0, 0));
193  dim = atoi(PQgetvalue(res, 0, 1));
194 
195  PQclear(res);
196 #endif
197  }
198 
199  if (!ftype_tmp)
200  return NULL;
201 
202  ftype = G_str_replace(ftype_tmp, " ", "");
203  G_free(ftype_tmp);
204  ftype_tmp = NULL;
205  G_str_to_lower(ftype);
206 
207  if (dim == 3) {
208  ftype_tmp = (char *) G_malloc(3 + strlen(ftype) + 1);
209  sprintf(ftype_tmp, "3D %s", ftype);
210  G_free(ftype);
211  ftype = ftype_tmp;
212  }
213 
214  return ftype;
215 }
216 
217 /*!
218  \brief Get header info for non-native formats
219 
220  \param Map pointer to Map_info structure
221 
222  \return pointer to Format_info structure
223  \return NULL for native format
224 */
225 const struct Format_info* Vect_get_finfo(const struct Map_info *Map)
226 {
227  /* do not check Map-format which is native (see
228  * GRASS_VECTOR_EXTERNAL_IMMEDIATE) */
229 
230  if (Map->fInfo.ogr.driver_name || Map->fInfo.pg.conninfo)
231  return &(Map->fInfo);
232 
233  return NULL;
234 }
235 
236 /*!
237  \brief Get topology type (relevant only for non-native formats)
238 
239  \param Map pointer to Map_info structure
240  \param[out] toposchema Topology schema name or NULL
241  \param[out] topogeom TopoGeometry column name or NULL
242  \param[out] topo_geo_only TRUE for Topo-Geo data model or NULL
243 
244  \return GV_TOPO_NATIVE for native format
245  \return GV_TOPO_PSEUDO for pseudo-topology
246  \return GV_TOPO_POSTGIS for PostGIS Topology
247 */
249  char **toposchema, char **topogeom, int* topo_geo_only)
250 {
251  if (Map->format == GV_FORMAT_OGR ||
252  Map->format == GV_FORMAT_OGR_DIRECT) {
253 #ifndef HAVE_OGR
254  G_warning(_("GRASS is not compiled with OGR support"));
255 #else
256  return GV_TOPO_PSEUDO;
257 #endif
258  }
259 
260  if (Map->format == GV_FORMAT_POSTGIS) {
261  const struct Format_info_pg *pg_info;
262 
263  pg_info = &(Map->fInfo.pg);
264  if (pg_info->toposchema_name) {
265  if (toposchema)
266  *toposchema = G_store(pg_info->toposchema_name);
267  if (topogeom)
268  *topogeom = G_store(pg_info->topogeom_column);
269  if (topo_geo_only)
270  *topo_geo_only = pg_info->topo_geo_only;
271 
272  return GV_TOPO_POSTGIS;
273  }
274  else {
275  return GV_TOPO_PSEUDO;
276  }
277  }
278 
279  return GV_TOPO_NATIVE;
280 }
char * toposchema_name
Topology schema name and id.
Definition: dig_structs.h:699
#define G_malloc(n)
Definition: defs/gis.h:112
const struct Format_info * Vect_get_finfo(const struct Map_info *Map)
Get header info for non-native formats.
Definition: header_finfo.c:225
PGconn * conn
PGconn object (generated by PQconnectdb)
Definition: dig_structs.h:663
OGRDataSourceH ds
Pointer to OGRDataSource.
Definition: dig_structs.h:542
#define DB_SQL_MAX
Definition: dbmi.h:142
#define GV_FORMAT_OGR
OGR format.
Definition: dig_defines.h:85
const char * Vect_get_finfo_geometry_type(const struct Map_info *Map)
Get geometry type as string (relevant only for non-native formats)
Definition: header_finfo.c:144
void G_free(void *)
Free allocated memory.
Definition: gis/alloc.c:149
char * dsn
OGR datasource name.
Definition: dig_structs.h:525
struct Format_info fInfo
Format info for non-native formats.
Definition: dig_structs.h:1415
char * table_name
Table name.
Definition: dig_structs.h:619
#define NULL
Definition: ccmath.h:32
char * db_name
Database name (derived from conninfo)
Definition: dig_structs.h:611
char * topogeom_column
TopoGeometry column (feature table)
Definition: dig_structs.h:695
char * G_str_replace(const char *, const char *, const char *)
Replace all occurrences of old_str in buffer with new_str.
Definition: strings.c:189
char * Vect_get_finfo_layer_name(const struct Map_info *Map)
Get layer name (relevant only for non-native formats)
Definition: header_finfo.c:72
Non-native format info (PostGIS)
Definition: dig_structs.h:602
struct Format_info_pg pg
PostGIS info.
Definition: dig_structs.h:726
int Vect_get_finfo_topology_info(const struct Map_info *Map, char **toposchema, char **topogeom, int *topo_geo_only)
Get topology type (relevant only for non-native formats)
Definition: header_finfo.c:248
#define GV_FORMAT_OGR_DIRECT
OGR format (direct access)
Definition: dig_defines.h:87
struct Format_info_ogr ogr
OGR info.
Definition: dig_structs.h:722
int topo_geo_only
Topology format.
Definition: dig_structs.h:707
void G_str_to_lower(char *)
Convert string to lower case.
Definition: strings.c:378
#define GV_TOPO_POSTGIS
PostGIS topology - external PostGIS format.
Definition: dig_defines.h:96
Vector map info.
Definition: dig_structs.h:1259
#define GV_FORMAT_POSTGIS
PostGIS format.
Definition: dig_defines.h:89
char * layer_name
OGR layer name.
Definition: dig_structs.h:529
#define GV_TOPO_PSEUDO
Pseudo-topology - external simple features (OGR/PostGIS) format.
Definition: dig_defines.h:94
const char * Vect_get_full_name(const struct Map_info *)
Get fully qualified name of vector map.
char * conninfo
Connection string.
Definition: dig_structs.h:607
void G_warning(const char *,...) __attribute__((format(printf
PGresult * res
Definition: dig_structs.h:664
char * driver_name
OGR driver name.
Definition: dig_structs.h:521
#define _(str)
Definition: glocale.h:10
const char * Vect_get_finfo_dsn_name(const struct Map_info *Map)
Get datasource name (relevant only for non-native formats)
Definition: header_finfo.c:36
int format
Map format (native, ogr, postgis)
Definition: dig_structs.h:1271
char * G_store(const char *)
Copy string to allocated memory.
Definition: strings.c:87
OGRLayerH layer
Pointer to OGRLayer.
Definition: dig_structs.h:546
int G_asprintf(char **, const char *,...) __attribute__((format(printf
const char * name
Definition: named_colr.c:7
char * schema_name
Schema name.
Definition: dig_structs.h:615
Non-native format info (currently only OGR is implemented)
Definition: dig_structs.h:713
int G_debug(int, const char *,...) __attribute__((format(printf
const char * Vect_get_finfo_format_info(const struct Map_info *Map)
Get format info as string (relevant only for non-native formats)
Definition: header_finfo.c:108
#define GV_TOPO_NATIVE
GRASS topology - native format.
Definition: dig_defines.h:92