GRASS GIS 8 Programmer's Manual  8.4.0dev(2024)-112dd97adf
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
17  gmail.com>
18  */
19 
20 #include <string.h>
21 
22 #include <grass/vector.h>
23 #include <grass/glocale.h>
24 
25 /*!
26  \brief Get datasource name (relevant only for non-native formats)
27 
28  Returns:
29  - datasource name for OGR format (GV_FORMAT_OGR and GV_FORMAT_OGR_DIRECT)
30  - database name for PostGIS format (GV_FORMAT_POSTGIS)
31 
32  \param Map pointer to Map_info structure
33 
34  \return string containing OGR/PostGIS datasource name
35  \return NULL on error (map format is native)
36  */
37 const char *Vect_get_finfo_dsn_name(struct Map_info *Map)
38 {
39  if (Map->format == GV_FORMAT_OGR || 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
64  (<schema>.<table>)
65 
66  Note: allocated string should be freed by G_free()
67 
68  \param Map pointer to Map_info structure
69 
70  \return string containing layer name
71  \return NULL on error (map format is native)
72  */
74 {
75  char *name;
76 
77  name = NULL;
78  if (Map->format == GV_FORMAT_OGR || Map->format == GV_FORMAT_OGR_DIRECT) {
79 #ifndef HAVE_OGR
80  G_warning(_("GRASS is not compiled with OGR support"));
81 #endif
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(struct Map_info *Map)
109 {
110  if (Map->format == GV_FORMAT_OGR || Map->format == GV_FORMAT_OGR_DIRECT) {
111 #ifndef HAVE_OGR
112  G_warning(_("GRASS is not compiled with OGR support"));
113 #else
114  if (!Map->fInfo.ogr.ds)
115  return NULL;
116 
117  return OGR_Dr_GetName(OGR_DS_GetDriver(Map->fInfo.ogr.ds));
118 #endif
119  }
120  else if (Map->format == GV_FORMAT_POSTGIS) {
121 #ifndef HAVE_OGR
122  G_warning(_("GRASS is not compiled with PostgreSQL support"));
123 #else
124  return "PostgreSQL";
125 #endif
126  }
127 
128  return NULL;
129 }
130 
131 /*!
132  \brief Get geometry type as string (relevant only for non-native formats)
133 
134  Note: All inner spaces are removed, function returns feature type in
135  lowercase.
136 
137  \param Map pointer to Map_info structure
138 
139  \return allocated string containing geometry type info
140  (point, linestring, polygon, ...)
141  \return NULL on error (map format is native)
142  */
143 const char *Vect_get_finfo_geometry_type(struct Map_info *Map)
144 {
145  int dim;
146  char *ftype, *ftype_tmp;
147 
148  ftype_tmp = ftype = NULL;
149  if (Map->format == GV_FORMAT_OGR || Map->format == GV_FORMAT_OGR_DIRECT) {
150 #ifndef HAVE_OGR
151  G_warning(_("GRASS is not compiled with OGR support"));
152 #else
153  OGRwkbGeometryType Ogr_geom_type;
154  OGRFeatureDefnH Ogr_feature_defn;
155 
156  if (!Map->fInfo.ogr.layer)
157  return NULL;
158 
159  dim = -1;
160 
161  Ogr_feature_defn = OGR_L_GetLayerDefn(Map->fInfo.ogr.layer);
162  Ogr_geom_type = wkbFlatten(OGR_FD_GetGeomType(Ogr_feature_defn));
163 
164  ftype_tmp = G_store(OGRGeometryTypeToName(Ogr_geom_type));
165 #endif
166  }
167  else if (Map->format == GV_FORMAT_POSTGIS) {
168 #ifndef HAVE_POSTGRES
169  G_warning(_("GRASS is not compiled with PostgreSQL support"));
170 #else
171  char stmt[DB_SQL_MAX];
172 
173  const struct Format_info_pg *pg_info;
174 
175  PGresult *res;
176 
177  pg_info = &(Map->fInfo.pg);
178  sprintf(stmt,
179  "SELECT type,coord_dimension FROM geometry_columns "
180  "WHERE f_table_schema = '%s' AND f_table_name = '%s'",
181  pg_info->schema_name, pg_info->table_name);
182  G_debug(2, "SQL: %s", stmt);
183 
184  res = PQexec(pg_info->conn, stmt);
185  if (!res || PQresultStatus(res) != PGRES_TUPLES_OK ||
186  PQntuples(res) != 1) {
187  G_debug(1, "Unable to get feature type: %s",
188  PQresultErrorMessage(res));
189  return NULL;
190  }
191  ftype_tmp = G_store(PQgetvalue(res, 0, 0));
192  dim = atoi(PQgetvalue(res, 0, 1));
193 
194  PQclear(res);
195 #endif
196  }
197 
198  if (!ftype_tmp)
199  return NULL;
200 
201  ftype = G_str_replace(ftype_tmp, " ", "");
202  G_free(ftype_tmp);
203  ftype_tmp = NULL;
204  G_str_to_lower(ftype);
205 
206  if (dim == 3) {
207  ftype_tmp = (char *)G_malloc(3 + strlen(ftype) + 1);
208  sprintf(ftype_tmp, "3D %s", ftype);
209  G_free(ftype);
210  ftype = ftype_tmp;
211  }
212 
213  return ftype;
214 }
215 
216 /*!
217  \brief Get header info for non-native formats
218 
219  \param Map pointer to Map_info structure
220 
221  \return pointer to Format_info structure
222  \return NULL for native format
223  */
224 const struct Format_info *Vect_get_finfo(struct Map_info *Map)
225 {
226  /* do not check Map-format which is native (see
227  * GRASS_VECTOR_EXTERNAL_IMMEDIATE) */
228 
229  if (Map->fInfo.ogr.driver_name || Map->fInfo.pg.conninfo)
230  return &(Map->fInfo);
231 
232  return NULL;
233 }
234 
235 /*!
236  \brief Get topology type (relevant only for non-native formats)
237 
238  \param Map pointer to Map_info structure
239  \param[out] toposchema Topology schema name or NULL
240  \param[out] topogeom TopoGeometry column name or NULL
241  \param[out] topo_geo_only TRUE for Topo-Geo data model or NULL
242 
243  \return GV_TOPO_NATIVE for native format
244  \return GV_TOPO_PSEUDO for pseudo-topology
245  \return GV_TOPO_POSTGIS for PostGIS Topology
246  */
247 int Vect_get_finfo_topology_info(struct Map_info *Map, char **toposchema,
248  char **topogeom, int *topo_geo_only)
249 {
250  if (Map->format == GV_FORMAT_OGR || Map->format == GV_FORMAT_OGR_DIRECT) {
251 #ifndef HAVE_OGR
252  G_warning(_("GRASS is not compiled with OGR support"));
253 #else
254  return GV_TOPO_PSEUDO;
255 #endif
256  }
257 
258  if (Map->format == GV_FORMAT_POSTGIS) {
259  const struct Format_info_pg *pg_info;
260 
261  pg_info = &(Map->fInfo.pg);
262  if (pg_info->toposchema_name) {
263  if (toposchema)
264  *toposchema = G_store(pg_info->toposchema_name);
265  if (topogeom)
266  *topogeom = G_store(pg_info->topogeom_column);
267  if (topo_geo_only)
268  *topo_geo_only = pg_info->topo_geo_only;
269 
270  return GV_TOPO_POSTGIS;
271  }
272  else {
273  return GV_TOPO_PSEUDO;
274  }
275  }
276 
277  return GV_TOPO_NATIVE;
278 }
#define NULL
Definition: ccmath.h:32
#define DB_SQL_MAX
Definition: dbmi.h:142
void G_free(void *)
Free allocated memory.
Definition: gis/alloc.c:150
void G_warning(const char *,...) __attribute__((format(printf
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
#define G_malloc(n)
Definition: defs/gis.h:94
int G_asprintf(char **, const char *,...) __attribute__((format(printf
void G_str_to_lower(char *)
Convert string to lower case.
Definition: strings.c:383
int G_debug(int, const char *,...) __attribute__((format(printf
char * G_store(const char *)
Copy string to allocated memory.
Definition: strings.c:87
const char * Vect_get_full_name(struct Map_info *)
Get fully qualified name of vector map.
#define GV_FORMAT_POSTGIS
PostGIS format.
Definition: dig_defines.h:89
#define GV_TOPO_POSTGIS
PostGIS topology - external PostGIS format.
Definition: dig_defines.h:96
#define GV_TOPO_NATIVE
GRASS topology - native format.
Definition: dig_defines.h:92
#define GV_FORMAT_OGR_DIRECT
OGR format (direct access)
Definition: dig_defines.h:87
#define GV_FORMAT_OGR
OGR format.
Definition: dig_defines.h:85
#define GV_TOPO_PSEUDO
Pseudo-topology - external simple features (OGR/PostGIS) format.
Definition: dig_defines.h:94
#define _(str)
Definition: glocale.h:10
const struct Format_info * Vect_get_finfo(struct Map_info *Map)
Get header info for non-native formats.
Definition: header_finfo.c:224
char * Vect_get_finfo_layer_name(struct Map_info *Map)
Get layer name (relevant only for non-native formats)
Definition: header_finfo.c:73
const char * Vect_get_finfo_format_info(struct Map_info *Map)
Get format info as string (relevant only for non-native formats)
Definition: header_finfo.c:108
int Vect_get_finfo_topology_info(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:247
const char * Vect_get_finfo_dsn_name(struct Map_info *Map)
Get datasource name (relevant only for non-native formats)
Definition: header_finfo.c:37
const char * Vect_get_finfo_geometry_type(struct Map_info *Map)
Get geometry type as string (relevant only for non-native formats)
Definition: header_finfo.c:143
const char * name
Definition: named_colr.c:6
char * dsn
OGR datasource name.
Definition: dig_structs.h:513
char * driver_name
OGR driver name.
Definition: dig_structs.h:509
OGRDataSourceH ds
Pointer to OGRDataSource.
Definition: dig_structs.h:530
char * layer_name
OGR layer name.
Definition: dig_structs.h:517
OGRLayerH layer
Pointer to OGRLayer.
Definition: dig_structs.h:534
Non-native format info (PostGIS)
Definition: dig_structs.h:590
char * db_name
Database name (derived from conninfo)
Definition: dig_structs.h:598
char * schema_name
Schema name.
Definition: dig_structs.h:602
PGconn * conn
PGconn object (generated by PQconnectdb)
Definition: dig_structs.h:650
char * toposchema_name
Topology schema name and id.
Definition: dig_structs.h:686
char * conninfo
Connection string.
Definition: dig_structs.h:594
PGresult * res
Definition: dig_structs.h:651
char * topogeom_column
TopoGeometry column (feature table)
Definition: dig_structs.h:682
int topo_geo_only
Topology format.
Definition: dig_structs.h:694
char * table_name
Table name.
Definition: dig_structs.h:606
Non-native format info (currently only OGR is implemented)
Definition: dig_structs.h:700
struct Format_info_pg pg
PostGIS info.
Definition: dig_structs.h:712
struct Format_info_ogr ogr
OGR info.
Definition: dig_structs.h:708
Vector map info.
Definition: dig_structs.h:1243
int format
Map format (native, ogr, postgis)
Definition: dig_structs.h:1255
struct Format_info fInfo
Format info for non-native formats.
Definition: dig_structs.h:1400