GRASS GIS 8 Programmer's Manual  8.5.0dev(2025)-565e82de51
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  const char *mname = Vect_get_full_name(Map);
53  G_debug(1, "Native vector format detected for <%s>", mname);
54  G_free((void *)mname);
55 
56  return NULL;
57 }
58 
59 /*!
60  \brief Get layer name (relevant only for non-native formats)
61 
62  Returns:
63  - layer name for OGR format (GV_FORMAT_OGR and GV_FORMAT_OGR_DIRECT)
64  - table name for PostGIS format (GV_FORMAT_POSTGIS) including schema
65  (<schema>.<table>)
66 
67  Note: allocated string should be freed by G_free()
68 
69  \param Map pointer to Map_info structure
70 
71  \return string containing layer name
72  \return NULL on error (map format is native)
73  */
75 {
76  char *name;
77 
78  name = NULL;
79  if (Map->format == GV_FORMAT_OGR || Map->format == GV_FORMAT_OGR_DIRECT) {
80 #ifndef HAVE_OGR
81  G_warning(_("GRASS is not compiled with OGR support"));
82 #endif
84  }
85  else if (Map->format == GV_FORMAT_POSTGIS) {
86 #ifndef HAVE_POSTGRES
87  G_warning(_("GRASS is not compiled with PostgreSQL support"));
88 #endif
89  G_asprintf(&name, "%s.%s", Map->fInfo.pg.schema_name,
90  Map->fInfo.pg.table_name);
91  }
92  else {
93  const char *mname = Vect_get_full_name(Map);
94  G_debug(1, "Native vector format detected for <%s>", mname);
95  G_free((void *)mname);
96  }
97 
98  return name;
99 }
100 
101 /*!
102  \brief Get format info as string (relevant only for non-native formats)
103 
104  \param Map pointer to Map_info structure
105 
106  \return string containing name of OGR format
107  \return "PostgreSQL" for PostGIS format (GV_FORMAT_POSTGIS)
108  \return NULL on error (or on missing OGR/PostgreSQL support)
109  */
110 const char *Vect_get_finfo_format_info(struct Map_info *Map)
111 {
112  if (Map->format == GV_FORMAT_OGR || Map->format == GV_FORMAT_OGR_DIRECT) {
113 #ifndef HAVE_OGR
114  G_warning(_("GRASS is not compiled with OGR support"));
115 #else
116  if (!Map->fInfo.ogr.ds)
117  return NULL;
118 
119  return OGR_Dr_GetName(OGR_DS_GetDriver(Map->fInfo.ogr.ds));
120 #endif
121  }
122  else if (Map->format == GV_FORMAT_POSTGIS) {
123 #ifndef HAVE_OGR
124  G_warning(_("GRASS is not compiled with PostgreSQL support"));
125 #else
126  return "PostgreSQL";
127 #endif
128  }
129 
130  return NULL;
131 }
132 
133 /*!
134  \brief Get geometry type as string (relevant only for non-native formats)
135 
136  Note: All inner spaces are removed, function returns feature type in
137  lowercase.
138 
139  \param Map pointer to Map_info structure
140 
141  \return allocated string containing geometry type info
142  (point, linestring, polygon, ...)
143  \return NULL on error (map format is native)
144  */
145 const char *Vect_get_finfo_geometry_type(struct Map_info *Map)
146 {
147  int dim;
148  char *ftype, *ftype_tmp;
149 
150  ftype_tmp = ftype = NULL;
151  if (Map->format == GV_FORMAT_OGR || 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,
181  "SELECT type,coord_dimension FROM geometry_columns "
182  "WHERE f_table_schema = '%s' AND f_table_name = '%s'",
183  pg_info->schema_name, pg_info->table_name);
184  G_debug(2, "SQL: %s", stmt);
185 
186  res = PQexec(pg_info->conn, stmt);
187  if (!res || PQresultStatus(res) != PGRES_TUPLES_OK ||
188  PQntuples(res) != 1) {
189  G_debug(1, "Unable to get feature type: %s",
190  PQresultErrorMessage(res));
191  return NULL;
192  }
193  ftype_tmp = G_store(PQgetvalue(res, 0, 0));
194  dim = atoi(PQgetvalue(res, 0, 1));
195 
196  PQclear(res);
197 #endif
198  }
199 
200  if (!ftype_tmp)
201  return NULL;
202 
203  ftype = G_str_replace(ftype_tmp, " ", "");
204  G_free(ftype_tmp);
205  ftype_tmp = NULL;
206  G_str_to_lower(ftype);
207 
208  if (dim == 3) {
209  ftype_tmp = (char *)G_malloc(3 + strlen(ftype) + 1);
210  sprintf(ftype_tmp, "3D %s", ftype);
211  G_free(ftype);
212  ftype = ftype_tmp;
213  }
214 
215  return ftype;
216 }
217 
218 /*!
219  \brief Get header info for non-native formats
220 
221  \param Map pointer to Map_info structure
222 
223  \return pointer to Format_info structure
224  \return NULL for native format
225  */
226 const struct Format_info *Vect_get_finfo(struct Map_info *Map)
227 {
228  /* do not check Map-format which is native (see
229  * GRASS_VECTOR_EXTERNAL_IMMEDIATE) */
230 
231  if (Map->fInfo.ogr.driver_name || Map->fInfo.pg.conninfo)
232  return &(Map->fInfo);
233 
234  return NULL;
235 }
236 
237 /*!
238  \brief Get topology type (relevant only for non-native formats)
239 
240  \param Map pointer to Map_info structure
241  \param[out] toposchema Topology schema name or NULL
242  \param[out] topogeom TopoGeometry column name or NULL
243  \param[out] topo_geo_only TRUE for Topo-Geo data model or NULL
244 
245  \return GV_TOPO_NATIVE for native format
246  \return GV_TOPO_PSEUDO for pseudo-topology
247  \return GV_TOPO_POSTGIS for PostGIS Topology
248  */
249 int Vect_get_finfo_topology_info(struct Map_info *Map, char **toposchema,
250  char **topogeom, int *topo_geo_only)
251 {
252  if (Map->format == GV_FORMAT_OGR || 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 }
#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:226
char * Vect_get_finfo_layer_name(struct Map_info *Map)
Get layer name (relevant only for non-native formats)
Definition: header_finfo.c:74
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:110
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:249
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:145
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