123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356 |
- #include <string.h>
- #include <grass/gis.h>
- #include <grass/vector.h>
- #include <grass/dbmi.h>
- #include <grass/gprojects.h>
- #include <grass/glocale.h>
- #ifdef HAVE_OGR
- #include "ogr_api.h"
- #endif
- #ifdef HAVE_POSTGRES
- #include <libpq-fe.h>
- #endif
- #include "local_proto.h"
- static int cmp(const void *, const void *);
- static char **format_list(int *, size_t *);
- static char *feature_type(const char *);
- #ifdef HAVE_OGR
- static int list_layers_ogr(FILE *, const char *, char **, int);
- #endif /* HAVE_OGR */
- #ifdef HAVE_POSTGRES
- static int list_layers_pg(FILE *, const char *, char **, int);
- #endif /* HAVE_POSTGRES */
- int cmp(const void *a, const void *b)
- {
- return strcmp(*(char **)a, *(char **)b);
- }
- char **format_list(int *count, size_t *len)
- {
- int i;
- char **list;
- list = NULL;
- *count = 0;
- if (len)
- *len = 0;
- #ifdef HAVE_OGR
- char buf[2000];
-
- OGRSFDriverH Ogr_driver;
-
- /* Open OGR DSN */
- OGRRegisterAll();
- G_debug(2, "driver count = %d", OGRGetDriverCount());
- for (i = 0; i < OGRGetDriverCount(); i++) {
- Ogr_driver = OGRGetDriver(i);
- G_debug(2, "driver %d/%d : %s", i, OGRGetDriverCount(),
- OGR_Dr_GetName(Ogr_driver));
-
- list = G_realloc(list, ((*count) + 1) * sizeof(char *));
- /* chg white space to underscore in OGR driver names */
- sprintf(buf, "%s", OGR_Dr_GetName(Ogr_driver));
- G_strchg(buf, ' ', '_');
- list[(*count)++] = G_store(buf);
- if (len)
- *len += strlen(buf) + 1; /* + ',' */
- }
- /* order formats by name */
- qsort(list, *count, sizeof(char *), cmp);
- #endif
- #if defined HAVE_POSTGRES && !defined HAVE_OGR
- list = G_realloc(list, ((*count) + 1) * sizeof(char *));
- list[(*count)++] = G_store("PostgreSQL");
- if (len)
- *len += strlen("PostgreSQL") + 1;
- #endif
- return list;
- }
- char *feature_type(const char *ftype)
- {
- char *ftype_ret;
- ftype_ret = G_str_replace(ftype, " ", "");
- G_str_to_lower(ftype_ret);
- /* let's OS to release the memory */
- return ftype_ret;
- }
- void list_formats(void)
- {
- int i, count;
- char **list;
-
- G_message(_("Supported formats:"));
- list = format_list(&count, NULL);
-
- for (i = 0; i < count; i++)
- fprintf(stdout, "%s\n", list[i]);
- fflush(stdout);
- G_free(list);
- }
- int list_layers(FILE *fd, const char *dsn, char **layer, int print_types, int use_ogr)
- {
- if (!use_ogr) {
- #ifdef HAVE_POSTGRES
- return list_layers_pg(fd, dsn, layer, print_types);
- #else
- G_fatal_error(_("GRASS is not compiled with PostgreSQL support"));
- #endif
- }
- #ifdef HAVE_OGR
- return list_layers_ogr(fd, dsn, layer, print_types);
- #else
- G_fatal_error(_("GRASS is not compiled with OGR support"));
- #endif
- return -1;
- }
- void get_table_name(const char *table, char **table_name, char **schema_name)
- {
- char **tokens;
- tokens = G_tokenize(table, ".");
- if (G_number_of_tokens(tokens) > 1) {
- *schema_name = G_store(tokens[0]);
- *table_name = G_store(tokens[1]);
- }
- else {
- *schema_name = NULL;
- *table_name = G_store(tokens[0]);
- }
-
- G_free_tokens(tokens);
- }
- #ifdef HAVE_POSTGRES
- int list_layers_pg(FILE *fd, const char *conninfo, char **table, int print_types)
- {
- int row, ntables, ret, print_schema;
- char *value_schema, *value_table, *value_type, *value_column;
- char *schema_name, *table_name;
-
- PGconn *conn;
- PGresult *res;
-
- dbString sql;
-
- ret = -1;
-
- conn = PQconnectdb(conninfo);
- G_debug(1, "PQconnectdb(): %s", conninfo);
- if (PQstatus(conn) == CONNECTION_BAD)
- G_fatal_error("%s\n%s", _("Connection to PostgreSQL database failed."),
- PQerrorMessage(conn));
-
- db_init_string(&sql);
- db_set_string(&sql, "SELECT f_table_schema, f_table_name, f_geometry_column, type "
- "FROM geometry_columns ORDER BY "
- "f_table_schema, f_table_name");
- G_debug(2, "SQL: %s", db_get_string(&sql));
- res = PQexec(conn, db_get_string(&sql));
- if (PQresultStatus(res) != PGRES_TUPLES_OK)
- G_fatal_error("%s\n%s", _("No feature tables found in database."),
- PQresultErrorMessage(res));
- /* get schema & table_name */
- table_name = schema_name = NULL;
- if (table)
- get_table_name(*table, &table_name, &schema_name);
-
- ntables = PQntuples(res);
- G_debug(3, " nrows = %d", ntables);
- if (fd)
- G_message(n_("PostGIS database <%s> contains %d feature table:",
- "PostGIS database <%s> contains %d feature tables:",
- ntables),
- PQdb(conn), ntables);
-
- /* report also schemas */
- print_schema = FALSE;
- if (fd) {
- for (row = 0; row < ntables; row++) {
- value_schema = PQgetvalue(res, row, 0);
- if (G_strcasecmp(value_schema, "public") != 0) {
- print_schema = TRUE;
- break;
- }
- }
- }
-
- /* report layers */
- for (row = 0; row < ntables; row++) {
- value_schema = PQgetvalue(res, row, 0);
- value_table = PQgetvalue(res, row, 1);
- value_column = PQgetvalue(res, row, 2);
- value_type = PQgetvalue(res, row, 3);
-
- if (fd) {
- if (print_types) {
- if (print_schema && G_strcasecmp(value_schema, "public") != 0)
- fprintf(fd, "%s.", value_schema);
-
- fprintf(fd, "%s,%s,0,%s\n", value_table,
- feature_type(value_type), value_column);
- }
- else {
- if (print_schema && G_strcasecmp(value_schema, "public") != 0)
- fprintf(fd, "%s.%s\n", value_schema, value_table);
- else
- fprintf(fd, "%s\n", value_table);
- }
- }
- if ((!schema_name || strcmp(value_schema, schema_name) == 0) &&
- table_name && strcmp(value_table, table_name) == 0) {
- ret = row;
- }
- }
-
- if (table_name)
- G_free(table_name);
- if (schema_name)
- G_free(schema_name);
-
- PQclear(res);
- PQfinish(conn);
- G_debug(1, "PQfinish()");
-
- return ret;
- }
- #endif /* HAVE_POSTGRES */
- #ifdef HAVE_OGR
- int list_layers_ogr(FILE *fd, const char *dsn, char **layer, int print_types)
- {
- int i, ret;
- int nlayers;
- char *layer_name;
-
- struct Key_Value *loc_proj_info, *loc_proj_units;
- struct Key_Value *proj_info, *proj_units;
- struct Cell_head loc_wind;
- OGRDataSourceH Ogr_ds;
- OGRLayerH Ogr_layer;
- OGRFeatureDefnH Ogr_featuredefn;
- OGRwkbGeometryType Ogr_geom_type;
-
- ret = -1;
- loc_proj_info = loc_proj_units = NULL;
- proj_info = proj_units = NULL;
- /* open OGR DSN */
- Ogr_ds = OGROpen(dsn, FALSE, NULL);
- if (!Ogr_ds) {
- G_fatal_error(_("Unable to open data source '%s'"), dsn);
- }
- /* Make a list of available layers */
- nlayers = OGR_DS_GetLayerCount(Ogr_ds);
- if (fd) {
- G_message(n_("Data source <%s> (format '%s') contains %d layer:",
- "Data source <%s> (format '%s') contains %d layers:",
- nlayers),
- dsn, OGR_Dr_GetName(OGR_DS_GetDriver(Ogr_ds)), nlayers);
- }
- else if (layer && !(*layer)) {
- /* return first layer by default (if layer not defined) */
- if (nlayers > 0) {
- Ogr_layer = OGR_DS_GetLayer(Ogr_ds, 0);
- Ogr_featuredefn = OGR_L_GetLayerDefn(Ogr_layer);
- *layer = G_store((char *) OGR_FD_GetName(Ogr_featuredefn));
- return 0;
- }
- return -1;
- }
- G_get_default_window(&loc_wind);
- if (print_types && loc_wind.proj != PROJECTION_XY) {
- loc_proj_info = G_get_projinfo();
- loc_proj_units = G_get_projunits();
- }
-
- for (i = 0; i < nlayers; i++) {
- Ogr_layer = OGR_DS_GetLayer(Ogr_ds, i);
- Ogr_featuredefn = OGR_L_GetLayerDefn(Ogr_layer);
- #if GDAL_VERSION_NUM < 1110000
- Ogr_geom_type = OGR_FD_GetGeomType(Ogr_featuredefn);
- #endif
- layer_name = (char *) OGR_FD_GetName(Ogr_featuredefn);
- if (fd) {
- if (print_types) {
- int proj_same, igeom;
- OGRSpatialReferenceH Ogr_projection;
- #if GDAL_VERSION_NUM >= 1110000
- OGRGeomFieldDefnH Ogr_geomdefn;
- #endif
- /* projection check */
- Ogr_projection = OGR_L_GetSpatialRef(Ogr_layer);
- proj_same = 0;
- G_suppress_warnings(TRUE);
- if (GPJ_osr_to_grass(&loc_wind, &proj_info,
- &proj_units, Ogr_projection, 0) < 0) {
- G_warning(_("Unable to convert input map projection to GRASS "
- "format. Projection check cannot be provided for "
- "OGR layer <%s>"), layer_name);
- }
- else {
- if (TRUE == G_compare_projections(loc_proj_info, loc_proj_units,
- proj_info, proj_units))
- proj_same = 1;
- else
- proj_same = 0;
- }
- G_suppress_warnings(FALSE);
- #if GDAL_VERSION_NUM >= 1110000
- for (igeom = 0; igeom < OGR_FD_GetGeomFieldCount(Ogr_featuredefn); igeom++) {
- Ogr_geomdefn = OGR_FD_GetGeomFieldDefn(Ogr_featuredefn, igeom);
- if (!Ogr_geomdefn) {
- G_warning(_("Invalid geometry column %d"), igeom);
- continue;
- }
- Ogr_geom_type = OGR_GFld_GetType(Ogr_geomdefn);
- fprintf(fd, "%s,%s,%d,%s\n", layer_name,
- feature_type(OGRGeometryTypeToName(Ogr_geom_type)),
- proj_same, OGR_GFld_GetNameRef(Ogr_geomdefn));
- }
- #else
- fprintf(fd, "%s,%s,%d,\n", layer_name,
- feature_type(OGRGeometryTypeToName(Ogr_geom_type)),
- proj_same);
- #endif
- }
- else {
- fprintf(fd, "%s\n", layer_name);
- }
- }
- if (layer)
- if (strcmp(layer_name, *layer) == 0) {
- ret = i;
- }
- }
- OGR_DS_Destroy(Ogr_ds);
- return ret;
- }
- #endif /* HAVE_OGR */
|