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 */
Vect_get_finfo_dsn_name(const struct Map_info * Map)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 */
Vect_get_finfo_layer_name(const struct Map_info * Map)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 */
Vect_get_finfo_format_info(const struct Map_info * Map)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 */
Vect_get_finfo_geometry_type(const struct Map_info * Map)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 */
Vect_get_finfo(const struct Map_info * Map)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 */
Vect_get_finfo_topology_info(const struct Map_info * Map,char ** toposchema,char ** topogeom,int * topo_geo_only)248 int Vect_get_finfo_topology_info(const struct Map_info *Map,
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 }
281