Пример #1
0
/*!
  \brief Initialize dbIndex

  \param index pointer to dbIndex to be initialized
*/
void db_init_index(dbIndex * index)
{
    db_init_string(&index->indexName);
    db_init_string(&index->tableName);
    index->numColumns = 0;
    index->columnNames = NULL;
    index->unique = 0;
}
Пример #2
0
static int get_stmt(FILE * fd, dbString * stmt)
{
    char buf[4000], buf2[4000];
    int len, row = 0;

    db_init_string(stmt);

    while (fgets(buf, 4000, fd) != NULL) {
	strcpy(buf2, buf);
	G_chop(buf2);
	len = strlen(buf2);

	if (buf2[len - 1] == ';') {	/* end of statement */
	    buf2[len - 1] = 0;	        /* truncate ';' */
	    /* append truncated */
	    db_append_string(stmt, buf2);	
	    return 1;
	}
	else {
	    /* append not truncated string (\n may be part of value) */
	    db_append_string(stmt, buf);	
	}
	row++;
    }

    if (row > 0)
	return 1;

    return 0;
}
Пример #3
0
int db__driver_describe_table(dbString * table_name, dbTable ** table)
{
    dbString sql;
    PGresult *res;

    db_init_string(&sql);

    db_set_string(&sql, "select * from ");
    db_append_string(&sql, db_get_string(table_name));
    db_append_string(&sql, " where 1 = 0");

    res = PQexec(pg_conn, db_get_string(&sql));

    if (!res || PQresultStatus(res) != PGRES_TUPLES_OK) {
	append_error(db_get_string(&sql));
	append_error("\n");
	append_error(PQerrorMessage(pg_conn));
	report_error();
	PQclear(res);
	return DB_FAILED;
    }

    if (describe_table(res, table, NULL) == DB_FAILED) {
	append_error("Cannot describe table\n");
	report_error();
	PQclear(res);
	return DB_FAILED;
    }

    PQclear(res);

    return DB_OK;
}
Пример #4
0
/*!
  \brief Delete table

  \param drvname driver name
  \param dbname database name
  \param tblname table name

  \return DB_OK on success
  \return DB_FAILED on failure
 */
int db_delete_table(const char *drvname, const char *dbname, const char *tblname)
{
    dbDriver *driver;
    dbString sql;

    G_debug(3, "db_delete_table(): driver = %s, db = %s, table = %s\n",
	    drvname, dbname, tblname);

    /* Open driver and database */
    driver = db_start_driver_open_database(drvname, dbname);
    if (driver == NULL) {
	G_warning(_("Unable open database <%s> by driver <%s>"), dbname,
		  drvname);
	return DB_FAILED;
    }

    /* Delete table */
    /* TODO test if the tables exist */
    db_init_string(&sql);
    db_set_string(&sql, "drop table ");
    db_append_string(&sql, tblname);
    G_debug(3, "%s", db_get_string(&sql));

    if (db_execute_immediate(driver, &sql) != DB_OK) {
	G_warning(_("Unable to drop table: '%s'"),
		  db_get_string(&sql));
	db_close_database_shutdown_driver(driver);
	return DB_FAILED;
    }

    db_close_database_shutdown_driver(driver);

    return DB_OK;
}
Пример #5
0
/*------------------------------------------------------------------------------------------------*/
int P_Drop_Aux_Table(dbDriver * driver, char *tab_name)
{
    dbString drop;

    db_init_string(&drop);
    db_append_string(&drop, "drop table ");
    db_append_string(&drop, tab_name);
    return db_execute_immediate(driver, &drop);
}
Пример #6
0
/* init error message */
void init_error(void)
{
    if (!errMsg) {
	errMsg = (dbString *) G_malloc(sizeof(dbString));
	db_init_string(errMsg);
    }

    db_set_string(errMsg, "DBMI-SQLite driver error:\n");
}
Пример #7
0
int db__send_Cstring(const char *s)
{
    dbString x;

    db_init_string(&x);
    db_set_string_no_copy(&x, (char *)s);

    return db__send_string(&x);
}
Пример #8
0
/*!
   \brief Fetches list of DB column names and types of vector map attribute table

   \param Map vector map
   \param field layer number

   \return list of column(s) types on success
   \retutn NULL on error 
 */
const char *Vect_get_column_names_types(struct Map_info *Map, int field)
{
    int num_dblinks, ncols, col;
    struct field_info *fi;
    dbDriver *driver = NULL;
    dbHandle handle;
    dbString table_name;
    dbTable *table;
    char buf[2000], temp_buf[2000];


    num_dblinks = Vect_get_num_dblinks(Map);
    if (num_dblinks <= 0)
	return (NULL);

    G_debug(3,
	    "Displaying column types for database connection of layer %d:",
	    field);
    if ((fi = Vect_get_field(Map, field)) == NULL)
	return (NULL);
    driver = db_start_driver(fi->driver);
    if (driver == NULL)
	return (NULL);
    db_init_handle(&handle);
    db_set_handle(&handle, fi->database, NULL);
    if (db_open_database(driver, &handle) != DB_OK)
	return (NULL);
    db_init_string(&table_name);
    db_set_string(&table_name, fi->table);
    if (db_describe_table(driver, &table_name, &table) != DB_OK)
	return (NULL);

    ncols = db_get_table_number_of_columns(table);
    sprintf(buf, " ");
    for (col = 0; col < ncols; col++) {
	if (col == 0)
	    sprintf(buf, "%s(%s)",
		    db_get_column_name(db_get_table_column(table, col)),
		    db_sqltype_name(db_get_column_sqltype
				    (db_get_table_column(table, col))));
	else {
	    sprintf(temp_buf, ",%s(%s)",
		    db_get_column_name(db_get_table_column(table, col)),
		    db_sqltype_name(db_get_column_sqltype
				    (db_get_table_column(table, col))));
	    strcat(buf, temp_buf);
	}
    }
    G_debug(3, "%s", buf);

    db_close_database(driver);
    db_shutdown_driver(driver);

    return G_store(G_chop(buf));
}
Пример #9
0
int Select(double *PartialX, double *PartialY, double *Interp,
           int line_num, dbDriver * driver, char *tab_name)
{
    int more;
    char buf[1024];
    dbString sql;
    dbTable *table;
    dbCursor cursor;
    dbColumn *PartialX_col, *PartialY_col, *Interp_col;
    dbValue *PartialX_value, *PartialY_value, *Interp_value;

    db_init_string(&sql);
    sprintf(buf,
	    "SELECT ID, Interp, X, Y FROM %s WHERE ID=%d",
	    tab_name, line_num);
    db_append_string(&sql, buf);

    if (db_open_select_cursor(driver, &sql, &cursor, DB_SEQUENTIAL) != DB_OK)
	return -1;

    table = db_get_cursor_table(&cursor);

    while (db_fetch(&cursor, DB_NEXT, &more) == DB_OK && more) {

	Interp_col = db_get_table_column(table, 1);
	PartialX_col = db_get_table_column(table, 2);
	PartialY_col = db_get_table_column(table, 3);

	if (db_sqltype_to_Ctype(db_get_column_sqltype(Interp_col)) ==
	    DB_C_TYPE_DOUBLE)
	    Interp_value = db_get_column_value(Interp_col);
	else
	    continue;

	if (db_sqltype_to_Ctype(db_get_column_sqltype(PartialX_col)) ==
	    DB_C_TYPE_DOUBLE)
	    PartialX_value = db_get_column_value(PartialX_col);
	else
	    continue;

	if (db_sqltype_to_Ctype(db_get_column_sqltype(PartialY_col)) ==
	    DB_C_TYPE_DOUBLE)
	    PartialY_value = db_get_column_value(PartialY_col);
	else
	    continue;

	*Interp += db_get_value_double(Interp_value);
	*PartialX += db_get_value_double(PartialX_value);
	*PartialY += db_get_value_double(PartialY_value);
    }
    db_close_cursor(&cursor);
    db_free_string(&sql);
    return DB_OK;
}
Пример #10
0
/*!
  \brief Select one (first) value from table/column for key/id

  \param driver DB driver
  \param tab table name
  \param key key column name
  \param id identifier in key column
  \param col name of column to select the value from
  \param[out] val dbValue to store within

  \return number of selected values
  \return -1 on error
 */
int db_select_value(dbDriver * driver, const char *tab, const char *key,
		    int id, const char *col, dbValue * val)
{
    int more, count;
    char buf[1024];
    dbString stmt;
    dbCursor cursor;
    dbColumn *column;
    dbValue *value;
    dbTable *table;

    if (key == NULL || strlen(key) == 0) {
	G_warning(_("Missing key column name"));
	return -1;
    }

    if (col == NULL || strlen(col) == 0) {
	G_warning(_("Missing column name"));
	return -1;
    }

    G_zero(val, sizeof(dbValue));
    sprintf(buf, "SELECT %s FROM %s WHERE %s = %d\n", col, tab, key, id);
    db_init_string(&stmt);
    db_append_string(&stmt, buf);

    if (db_open_select_cursor(driver, &stmt, &cursor, DB_SEQUENTIAL) != DB_OK)
	return (-1);

    table = db_get_cursor_table(&cursor);
    column = db_get_table_column(table, 0);	/* first column */
    value = db_get_column_value(column);

    /* fetch the data */
    count = 0;
    while (1) {
	if (db_fetch(&cursor, DB_NEXT, &more) != DB_OK)
	    return (-1);

	if (!more)
	    break;
	if (count == 0)
	    db_copy_value(val, value);
	count++;
    }
    db_close_cursor(&cursor);
    db_free_string(&stmt);

    return (count);
}
Пример #11
0
void print_columns(const struct Map_info *Map, const char *input_opt, const char *field_opt)
{
    int num_dblinks, col, ncols;

    struct field_info *fi;
    dbDriver *driver = NULL;
    dbHandle handle;
    dbString table_name;
    dbTable *table;

    num_dblinks = Vect_get_num_dblinks(Map);

    if (num_dblinks <= 0) {
	G_fatal_error(_("Database connection for map <%s> is not defined in DB file"),
		      input_opt);
    }

    G_message(_("Displaying column types/names for database connection of layer <%s>:"),
	      field_opt);

    if ((fi = Vect_get_field2(Map, field_opt)) == NULL)
	G_fatal_error(_("Database connection not defined for layer <%s>"),
		      field_opt);
    driver = db_start_driver(fi->driver);
    if (driver == NULL)
	G_fatal_error(_("Unable to open driver <%s>"),
		      fi->driver);
    db_init_handle(&handle);
    db_set_handle(&handle, fi->database, NULL);
    if (db_open_database(driver, &handle) != DB_OK)
	G_fatal_error(_("Unable to open database <%s> by driver <%s>"),
		      fi->database, fi->driver);
    db_init_string(&table_name);
    db_set_string(&table_name, fi->table);
    if (db_describe_table(driver, &table_name, &table) != DB_OK)
	G_fatal_error(_("Unable to describe table <%s>"),
		      fi->table);
    
    ncols = db_get_table_number_of_columns(table);
    for (col = 0; col < ncols; col++)
	fprintf(stdout, "%s|%s\n",
		db_sqltype_name(db_get_column_sqltype
				(db_get_table_column
				 (table, col))),
		db_get_column_name(db_get_table_column
				   (table, col)));
    
    db_close_database(driver);
    db_shutdown_driver(driver);
}
Пример #12
0
/* extract custom-namespaced attributes if any */
static int mk_attribs(int cat, struct field_info *Fi, dbDriver * Driver,
                      dbTable * Table, int attr_cols[], int attr_size,
                      int do_attr)
{
    int i, more;
    char buf[2000];
    dbString dbstring;
    dbColumn *Column;
    dbCursor cursor;
    dbValue *Value;

    /* include cat in any case */
    fprintf(fpsvg, "gg:cat=\"%d\" ", cat);

    /* skip attribs if none */
    if (do_attr == 0) {
        return 1;
    }

    /* create SQL-string and query attribs */
    db_init_string(&dbstring);

    sprintf(buf, "SELECT * FROM %s WHERE %s = %d", Fi->table, Fi->key, cat);

    db_set_string(&dbstring, buf);

    if (db_open_select_cursor(Driver, &dbstring, &cursor, DB_SEQUENTIAL) !=
            DB_OK) {
        G_fatal_error(_("Cannot select attributes for cat=%d"), cat);
    }
    else {
        if (db_fetch(&cursor, DB_NEXT, &more) != DB_OK) {
            G_fatal_error(_("Unable to fetch data from table"));
        }

        /* extract attribs and data if wanted */
        Table = db_get_cursor_table(&cursor);

        for (i = 0; i < attr_size; i++) {
            Column = db_get_table_column(Table, attr_cols[i]);
            Value = db_get_column_value(Column);
            db_convert_column_value_to_string(Column, &dbstring);
            strcpy(buf, db_get_column_name(Column));
            fprintf(fpsvg, "gg:%s=\"", G_tolcase(buf));
            print_escaped_for_xml(db_get_string(&dbstring));
            fprintf(fpsvg, "\" ");
        }
    }
    return 1;
}
Пример #13
0
static void create_table(struct Map_info *flowline_vec,
			 struct field_info **f_info, dbDriver ** driver,
			 int write_scalar, int use_sampled_map)
{
    dbString sql;
    char buf[200];
    dbDriver *drvr;
    struct field_info *fi;

    db_init_string(&sql);
    fi = Vect_default_field_info(flowline_vec, 1, NULL, GV_1TABLE);
    *f_info = fi;
    Vect_map_add_dblink(flowline_vec, 1, NULL, fi->table, GV_KEY_COLUMN,
			fi->database, fi->driver);
    drvr = db_start_driver_open_database(fi->driver,
					 Vect_subst_var(fi->database,
							flowline_vec));
    if (drvr == NULL) {
	G_fatal_error(_("Unable to open database <%s> by driver <%s>"),
		      Vect_subst_var(fi->database, flowline_vec), fi->driver);
    }
    db_set_error_handler_driver(drvr);

    *driver = drvr;
    sprintf(buf, "create table %s (cat integer, velocity double precision",
	    fi->table);
    db_set_string(&sql, buf);
    if (write_scalar)
	db_append_string(&sql, ", input double precision");
    if (use_sampled_map)
	db_append_string(&sql, ", sampled double precision");
    db_append_string(&sql, ")");

    db_begin_transaction(drvr);
    /* Create table */
    if (db_execute_immediate(drvr, &sql) != DB_OK) {
	G_fatal_error(_("Unable to create table: %s"), db_get_string(&sql));
    }
    if (db_create_index2(drvr, fi->table, fi->key) != DB_OK)
	G_warning(_("Unable to create index for table <%s>, key <%s>"),
		  fi->table, fi->key);
    /* Grant */
    if (db_grant_on_table
	(drvr, fi->table, DB_PRIV_SELECT, DB_GROUP | DB_PUBLIC) != DB_OK) {
	G_fatal_error(_("Unable to grant privileges on table <%s>"),
		      fi->table);
    }
}
Пример #14
0
/*!
  \brief Open select cursor

  \return DB_OK on success
  \return DB_FAILED on failure
 */
int db_d_open_select_cursor(void)
{
    dbCursor *cursor;
    int stat;
    dbToken token;
    dbString select;
    int mode;

    /* get the arg(s) */
    db_init_string(&select);
    DB_RECV_STRING(&select);
    DB_RECV_INT(&mode);

    /* create a cursor */
    cursor = (dbCursor *) db_malloc(sizeof(dbCursor));
    if (cursor == NULL)
	return db_get_error_code();
    token = db_new_token((dbAddress) cursor);
    if (token < 0)
	return db_get_error_code();
    db_init_cursor(cursor);

    /* call the procedure */
    stat = db_driver_open_select_cursor(&select, cursor, mode);
    db_free_string(&select);

    /* send the return code */
    if (stat != DB_OK) {
	DB_SEND_FAILURE();
	return DB_OK;
    }
    DB_SEND_SUCCESS();

    /* mark this as a readonly cursor */
    db_set_cursor_type_readonly(cursor);

    /* add this cursor to the cursors managed by the driver state */
    db__add_cursor_to_driver_state(cursor);

    /* results */
    DB_SEND_TOKEN(&token);
    DB_SEND_INT(cursor->type);
    DB_SEND_INT(cursor->mode);
    DB_SEND_TABLE_DEFINITION(cursor->table);
    return DB_OK;
}
Пример #15
0
int Insert_Interpolation(double Interp, int line_num, dbDriver * driver,
			 char *tab_name)
{
    char buf[1024];
    dbString sql;
    int ret;

    db_init_string(&sql);
    sprintf(buf, "INSERT INTO %s (ID, Interp)", tab_name);
    db_append_string(&sql, buf);
    sprintf(buf, " VALUES (%d, %lf)", line_num, Interp);
    db_append_string(&sql, buf);

    ret = db_execute_immediate(driver, &sql);
    db_free_string(&sql);

    return ret;
}
Пример #16
0
int UpDate(double partialX, double partialY, double Interp,
	   int line_num, dbDriver * driver, char *tab_name)
{
    char buf[1024];
    dbString sql;
    int ret;

    db_init_string(&sql);
    sprintf(buf,
	    "UPDATE %s SET Interp=%lf, X=%lf, Y=%lf WHERE ID=%d",
	    tab_name, Interp, partialX, partialY, line_num);
    db_append_string(&sql, buf);

    ret = db_execute_immediate(driver, &sql);
    db_free_string(&sql);

    return ret;
}
Пример #17
0
int db__driver_describe_table(dbString * table_name, dbTable ** table)
{
    dbString sql;
    MYSQL_RES *res;

    db_init_string(&sql);

    db_set_string(&sql, "select * from ");
    db_append_string(&sql, db_get_string(table_name));
    db_append_string(&sql, " where 1 = 0");

    if (mysql_query(connection, db_get_string(&sql)) != 0) {
	append_error(db_get_string(&sql));
	append_error("\n");
	append_error(mysql_error(connection));
	report_error();
	return DB_FAILED;
    }

    res = mysql_store_result(connection);

    if (res == NULL) {
	append_error(db_get_string(&sql));
	append_error("\n");
	append_error(mysql_error(connection));
	report_error();
	return DB_FAILED;
    }

    if (describe_table(res, table, NULL) == DB_FAILED) {
	append_error("Cannot describe table\n");
	report_error();
	mysql_free_result(res);
	return DB_FAILED;
    }

    mysql_free_result(res);

    db_set_table_name(*table, db_get_string(table_name));

    return DB_OK;
}
Пример #18
0
int db__driver_create_table(dbTable * table)
{
    dbString sql;
    int ret;

    G_debug(3, "db__driver_create_table()");

    db_init_string(&sql);

    db_table_to_sql(table, &sql);

    G_debug(3, " SQL: %s", db_get_string(&sql));

    ret = execute(db_get_string(&sql), NULL);

    if (ret == DB_FAILED) {
	db_d_append_error(_("Unable to create table"));
	db_d_report_error();
	return DB_FAILED;
    }

    return DB_OK;
}
Пример #19
0
/*!
  \brief Execute SQL statements

  \return DB_OK on success
  \return DB_FAILED on failure
 */
int db_d_execute_immediate(void)
{
    int stat;
    dbString SQLstatement;

    /* get the arg(s) */
    db_init_string(&SQLstatement);
    DB_RECV_STRING(&SQLstatement);

    /* call the procedure */
    stat = db_driver_execute_immediate(&SQLstatement);
    db_free_string(&SQLstatement);

    /* send the return code */
    if (stat != DB_OK) {
	DB_SEND_FAILURE();
	return DB_OK;
    }
    DB_SEND_SUCCESS();

    /* no results */
    return DB_OK;
}
Пример #20
0
int db__driver_create_table(dbTable * table)
{
    dbString sql;
    cursor *c;
    char msg[OD_MSG];
    char *emsg = NULL;
    SQLRETURN ret;
    SQLINTEGER err;

    G_debug(3, "db__driver_create_table()");

    db_init_string(&sql);
    db_table_to_sql(table, &sql);

    G_debug(3, " SQL: %s", db_get_string(&sql));

    c = alloc_cursor();
    if (c == NULL)
        return DB_FAILED;

    ret = SQLExecDirect(c->stmt, db_get_string(&sql), SQL_NTS);

    if ((ret != SQL_SUCCESS) && (ret != SQL_SUCCESS_WITH_INFO)) {
        SQLGetDiagRec(SQL_HANDLE_STMT, c->stmt, 1, NULL, &err, msg,
                      sizeof(msg), NULL);
        G_asprintf(&emsg, "SQLExecDirect():\n%s\n%s (%d)\n",
                   db_get_string(&sql), msg, (int)err);
        report_error(emsg);
        G_free(emsg);

        return DB_FAILED;
    }

    free_cursor(c);

    return DB_OK;
}
Пример #21
0
void QgsGrassVectorMapLayer::load()
{
  clear();

  if ( !mMap )
  {
    return;
  }

  // Attributes are not loaded for topo layers in which case field == 0
  if ( mField == 0 )
  {
    return;
  }

  QgsDebugMsg( QString( "cidxFieldIndex() = %1 cidxFieldNumCats() = %2" ).arg( cidxFieldIndex() ).arg( cidxFieldNumCats() ) );

  mFieldInfo = Vect_get_field( mMap->map(), mField ); // should work also with field = 0

  if ( !mFieldInfo )
  {
    QgsDebugMsg( "No field info -> no attribute table" );
  }
  else
  {
    QgsDebugMsg( "Field info found -> open database" );

    QFileInfo di( mMap->grassObject().mapsetPath() + "/vector/" + mMap->grassObject().name() + "/dbln" );
    mLastLoaded = di.lastModified();

    QString error;
    dbDriver *databaseDriver = openDriver( error );

    if ( !databaseDriver || !error.isEmpty() )
    {
      QgsDebugMsg( error );
    }
    else
    {
      QgsDebugMsg( "Database opened -> open select cursor" );
      QgsGrass::lock(); // not sure if lock is necessary
      dbString dbstr;
      db_init_string( &dbstr );
      db_set_string( &dbstr, ( char * )"select * from " );
      db_append_string( &dbstr, mFieldInfo->table );

      QgsDebugMsg( QString( "SQL: %1" ).arg( db_get_string( &dbstr ) ) );
      dbCursor databaseCursor;
      if ( db_open_select_cursor( databaseDriver, &dbstr, &databaseCursor, DB_SCROLL ) != DB_OK )
      {
        db_close_database_shutdown_driver( databaseDriver );
        QgsGrass::warning( "Cannot select attributes from table '" + QString( mFieldInfo->table ) + "'" );
      }
      else
      {
#ifdef QGISDEBUG
        int nRecords = db_get_num_rows( &databaseCursor );
        QgsDebugMsg( QString( "Number of records: %1" ).arg( nRecords ) );
#endif

        dbTable  *databaseTable = db_get_cursor_table( &databaseCursor );
        int nColumns = db_get_table_number_of_columns( databaseTable );

        // Read columns' description
        for ( int i = 0; i < nColumns; i++ )
        {
          QPair<double, double> minMax( DBL_MAX, -DBL_MAX );

          dbColumn *column = db_get_table_column( databaseTable, i );

          int ctype = db_sqltype_to_Ctype( db_get_column_sqltype( column ) );
          QVariant::Type qtype = QVariant::String; //default to string
          QgsDebugMsg( QString( "column = %1 ctype = %2" ).arg( db_get_column_name( column ) ).arg( ctype ) );

          QString ctypeStr;
          switch ( ctype )
          {
            case DB_C_TYPE_INT:
              ctypeStr = QStringLiteral( "integer" );
              qtype = QVariant::Int;
              break;
            case DB_C_TYPE_DOUBLE:
              ctypeStr = QStringLiteral( "double" );
              qtype = QVariant::Double;
              break;
            case DB_C_TYPE_STRING:
              ctypeStr = QStringLiteral( "string" );
              qtype = QVariant::String;
              break;
            case DB_C_TYPE_DATETIME:
              ctypeStr = QStringLiteral( "datetime" );
              qtype = QVariant::String;
              break;
          }
          mTableFields.append( QgsField( db_get_column_name( column ), qtype, ctypeStr,
                                         db_get_column_length( column ), db_get_column_precision( column ) ) );
          mMinMax << minMax;
          if ( G_strcasecmp( db_get_column_name( column ), mFieldInfo->key ) == 0 )
          {
            mKeyColumn = i;
          }
        }

        if ( mKeyColumn < 0 )
        {
          mTableFields.clear();
          QgsGrass::warning( QObject::tr( "Key column '%1' not found in the table '%2'" ).arg( mFieldInfo->key, mFieldInfo->table ) );
        }
        else
        {
          mHasTable = true;
          // Read attributes to the memory
          for ( ;; )
          {
            int more;

            if ( db_fetch( &databaseCursor, DB_NEXT, &more ) != DB_OK )
            {
              QgsDebugMsg( "Cannot fetch DB record" );
              break;
            }
            if ( !more )
            {
              break; // no more records
            }

            // Check cat value
            dbColumn *column = db_get_table_column( databaseTable, mKeyColumn );
            dbValue *value = db_get_column_value( column );

            if ( db_test_value_isnull( value ) )
            {
              continue;
            }
            int cat = db_get_value_int( value );
            if ( cat < 0 )
            {
              continue;
            }

            QList<QVariant> values;
            for ( int i = 0; i < nColumns; i++ )
            {
              column = db_get_table_column( databaseTable, i );
              int sqltype = db_get_column_sqltype( column );
              int ctype = db_sqltype_to_Ctype( sqltype );
              value = db_get_column_value( column );
              db_convert_value_to_string( value, sqltype, &dbstr );

              QgsDebugMsgLevel( QString( "column = %1 value = %2" ).arg( db_get_column_name( column ), db_get_string( &dbstr ) ), 3 );

              QVariant variant;
              if ( !db_test_value_isnull( value ) )
              {
                int iv;
                double dv;
                //layer.mAttributes[layer.nAttributes].values[i] = strdup( db_get_string( &dbstr ) );
                switch ( ctype )
                {
                  case DB_C_TYPE_INT:
                    iv = db_get_value_int( value );
                    variant = QVariant( iv );
                    mMinMax[i].first = std::min( mMinMax[i].first, ( double )iv );
                    mMinMax[i].second = std::min( mMinMax[i].second, ( double )iv );
                    break;
                  case DB_C_TYPE_DOUBLE:
                    dv = db_get_value_double( value );
                    variant = QVariant( dv );
                    mMinMax[i].first = std::min( mMinMax[i].first, dv );
                    mMinMax[i].second = std::min( mMinMax[i].second, dv );
                    break;
                  case DB_C_TYPE_STRING:
                    // Store as byte array so that codec may be used later
                    variant = QVariant( QByteArray( db_get_value_string( value ) ) );
                    break;
                  case DB_C_TYPE_DATETIME:
                    variant = QVariant( QByteArray( db_get_string( &dbstr ) ) );
                    break;
                  default:
                    variant = QVariant( QByteArray( db_get_string( &dbstr ) ) );
                }
              }
              QgsDebugMsgLevel( QString( "column = %1 variant = %2" ).arg( db_get_column_name( column ), variant.toString() ), 3 );
              values << variant;
            }
            mAttributes.insert( cat, values );
          }
        }
        mValid = true;
        db_close_cursor( &databaseCursor );
        db_close_database_shutdown_driver( databaseDriver );
        db_free_string( &dbstr );

        QgsDebugMsg( QString( "mTableFields.size = %1" ).arg( mTableFields.size() ) );
        QgsDebugMsg( QString( "number of attributes = %1" ).arg( mAttributes.size() ) );
      }
      QgsGrass::unlock();
    }
  }

  // Add cat if no attribute fields exist (otherwise qgis crashes)
  if ( mTableFields.size() == 0 )
  {
    mKeyColumn = 0;
    mTableFields.append( QgsField( QStringLiteral( "cat" ), QVariant::Int, QStringLiteral( "integer" ) ) );
    QPair<double, double> minMax( 0, 0 );

    if ( cidxFieldIndex() >= 0 )
    {
      int ncats, cat, type, id;

      ncats = Vect_cidx_get_num_cats_by_index( mMap->map(), cidxFieldIndex() );

      if ( ncats > 0 )
      {
        Vect_cidx_get_cat_by_index( mMap->map(), cidxFieldIndex(), 0, &cat, &type, &id );
        minMax.first = cat;

        Vect_cidx_get_cat_by_index( mMap->map(), cidxFieldIndex(), ncats - 1, &cat, &type, &id );
        minMax.second = cat;
      }
    }
    mMinMax << minMax;
  }
  mFields = mTableFields;
  mAttributeFields = mTableFields;

  QgsDebugMsg( QString( "layer loaded mTableFields.size() = %1 mAttributes.size() = %2" ).arg( mTableFields.size() ).arg( mAttributes.size() ) );
  mValid = true;
}
Пример #22
0
int close_streamvect(char *stream_vect)
{
    int r, c, r_nbr, c_nbr, done;
    GW_LARGE_INT i;
    CELL stream_id, stream_nbr;
    ASP_FLAG af;
    int next_node;
    struct sstack
    {
	int stream_id;
	int next_trib;
    } *nodestack;
    int top = 0, stack_step = 1000;
    int asp_r[9] = { 0, -1, -1, -1, 0, 1, 1, 1, 0 };
    int asp_c[9] = { 0, 1, 0, -1, -1, -1, 0, 1, 1 };
    struct Map_info Out;
    static struct line_pnts *Points;
    struct line_cats *Cats;
    dbDriver *driver;
    dbHandle handle;
    dbString table_name, dbsql, valstr;
    struct field_info *Fi;
    char *cat_col_name = "cat", buf[2000];
    struct Cell_head window;
    double north_offset, west_offset, ns_res, ew_res;
    int next_cat;

    G_message(_("Writing vector map <%s>..."), stream_vect);

    if (Vect_open_new(&Out, stream_vect, 0) < 0)
	G_fatal_error(_("Unable to create vector map <%s>"), stream_vect);
    
    nodestack = (struct sstack *)G_malloc(stack_step * sizeof(struct sstack));

    Points = Vect_new_line_struct();
    Cats = Vect_new_cats_struct();

    G_get_set_window(&window);
    ns_res = window.ns_res;
    ew_res = window.ew_res;
    north_offset = window.north - 0.5 * ns_res;
    west_offset = window.west + 0.5 * ew_res;

    next_cat = n_stream_nodes + 1;

    for (i = 0; i < n_outlets; i++, next_cat++) {
	G_percent(i, n_outlets, 2);
	r = outlets[i].r;
	c = outlets[i].c;
	cseg_get(&stream, &stream_id, r, c);

	if (!stream_id)
	    continue;

	Vect_reset_line(Points);
	Vect_reset_cats(Cats);

	/* outlet */
	Vect_cat_set(Cats, 1, stream_id);
	Vect_cat_set(Cats, 2, 2);
	Vect_append_point(Points, west_offset + c * ew_res,
			  north_offset - r * ns_res, 0);
	Vect_write_line(&Out, GV_POINT, Points, Cats);

	/* add root node to stack */
	G_debug(3, "add root node");
	top = 0;
	nodestack[top].stream_id = stream_id;
	nodestack[top].next_trib = 0;

	/* depth first post order traversal */
	G_debug(3, "traverse");
	while (top >= 0) {

	    done = 1;
	    stream_id = nodestack[top].stream_id;
	    G_debug(3, "stream_id %d", stream_id);
	    if (nodestack[top].next_trib < stream_node[stream_id].n_trib) {
		/* add to stack */
		next_node =
		    stream_node[stream_id].trib[nodestack[top].next_trib];
		G_debug(3, "add to stack: next %d, trib %d, n trib %d",
			next_node, nodestack[top].next_trib,
			stream_node[stream_id].n_trib);
		nodestack[top].next_trib++;
		top++;
		if (top >= stack_step) {
		    /* need more space */
		    stack_step += 1000;
		    nodestack =
			(struct sstack *)G_realloc(nodestack,
						   stack_step *
						   sizeof(struct sstack));
		}
		nodestack[top].next_trib = 0;
		nodestack[top].stream_id = next_node;
		done = 0;
		G_debug(3, "go further down");
	    }
	    if (done) {
		G_debug(3, "write stream segment");

		Vect_reset_line(Points);
		Vect_reset_cats(Cats);

		r_nbr = stream_node[stream_id].r;
		c_nbr = stream_node[stream_id].c;

		cseg_get(&stream, &stream_nbr, r_nbr, c_nbr);
		if (stream_nbr <= 0)
                    G_fatal_error(_("Stream id %d not set, top is %d, parent is %d"),
                                  stream_id, top, nodestack[top - 1].stream_id);

		Vect_cat_set(Cats, 1, stream_id);
		if (stream_node[stream_id].n_trib == 0)
		    Vect_cat_set(Cats, 2, 0);
		else
		    Vect_cat_set(Cats, 2, 1);

		Vect_append_point(Points, west_offset + c_nbr * ew_res,
				  north_offset - r_nbr * ns_res, 0);

		Vect_write_line(&Out, GV_POINT, Points, Cats);

		seg_get(&aspflag, (char *)&af, r_nbr, c_nbr);
		while (af.asp > 0) {
		    r_nbr = r_nbr + asp_r[(int)af.asp];
		    c_nbr = c_nbr + asp_c[(int)af.asp];
		    
		    cseg_get(&stream, &stream_nbr, r_nbr, c_nbr);
		    if (stream_nbr <= 0)
			G_fatal_error(_("Stream id not set while tracing"));

		    Vect_append_point(Points, west_offset + c_nbr * ew_res,
				      north_offset - r_nbr * ns_res, 0);
		    if (stream_nbr != stream_id) {
			/* first point of parent stream */
			break;
		    }
		    seg_get(&aspflag, (char *)&af, r_nbr, c_nbr);
		}

		Vect_write_line(&Out, GV_LINE, Points, Cats);

		top--;
	    }
	}
    }
    G_percent(n_outlets, n_outlets, 1);	/* finish it */

    G_message(_("Writing attribute data..."));

    /* Prepeare strings for use in db_* calls */
    db_init_string(&dbsql);
    db_init_string(&valstr);
    db_init_string(&table_name);
    db_init_handle(&handle);

    /* Preparing database for use */
    /* Create database for new vector map */
    Fi = Vect_default_field_info(&Out, 1, NULL, GV_1TABLE);
    driver = db_start_driver_open_database(Fi->driver,
					   Vect_subst_var(Fi->database,
							          &Out));
    if (driver == NULL) {
	G_fatal_error(_("Unable to start driver <%s>"), Fi->driver);
    }
    db_set_error_handler_driver(driver);

    G_debug(1, "table: %s", Fi->table);
    G_debug(1, "driver: %s", Fi->driver);
    G_debug(1, "database: %s", Fi->database);

    sprintf(buf,
	    "create table %s (%s integer, stream_type varchar(20), type_code integer)",
	    Fi->table, cat_col_name);
    db_set_string(&dbsql, buf);

    if (db_execute_immediate(driver, &dbsql) != DB_OK) {
	db_close_database(driver);
	db_shutdown_driver(driver);
	G_fatal_error(_("Unable to create table: '%s'"), db_get_string(&dbsql));
    }

    if (db_create_index2(driver, Fi->table, cat_col_name) != DB_OK)
	G_warning(_("Unable to create index on table <%s>"), Fi->table);

    if (db_grant_on_table(driver, Fi->table, DB_PRIV_SELECT,
			  DB_GROUP | DB_PUBLIC) != DB_OK)
	G_fatal_error(_("Unable to grant privileges on table <%s>"), Fi->table);

    db_begin_transaction(driver);

    /* stream nodes */
    for (i = 1; i <= n_stream_nodes; i++) {

	sprintf(buf, "insert into %s values ( %lld, \'%s\', %d )",
		Fi->table, i,
		(stream_node[i].n_trib > 0 ? "intermediate" : "start"),
		(stream_node[i].n_trib > 0));

	db_set_string(&dbsql, buf);

	if (db_execute_immediate(driver, &dbsql) != DB_OK) {
	    db_close_database(driver);
	    db_shutdown_driver(driver);
	    G_fatal_error(_("Unable to insert new row: '%s'"),
			  db_get_string(&dbsql));
	}
    }

    db_commit_transaction(driver);
    db_close_database_shutdown_driver(driver);

    Vect_map_add_dblink(&Out, 1, NULL, Fi->table,
			cat_col_name, Fi->database, Fi->driver);

    G_debug(1, "close vector");

    Vect_hist_command(&Out);
    Vect_build(&Out);
    Vect_close(&Out);

    G_free(nodestack);

    return 1;
}
Пример #23
0
int display_attr(struct Map_info *Map, int type, char *attrcol,
		 struct cat_list *Clist, LATTR *lattr, int chcat)
{
    int i, ltype, more;
    struct line_pnts *Points;
    struct line_cats *Cats;
    int cat;
    char buf[2000];
    struct field_info *fi;
    dbDriver *driver;
    dbString stmt, valstr, text;
    dbCursor cursor;
    dbTable *table;
    dbColumn *column;

    G_debug(2, "attr()");

    if (attrcol == NULL || *attrcol == '\0') {
	G_fatal_error(_("attrcol not specified, cannot display attributes"));
    }

    Points = Vect_new_line_struct();
    Cats = Vect_new_cats_struct();
    db_init_string(&stmt);
    db_init_string(&valstr);
    db_init_string(&text);

    fi = Vect_get_field(Map, lattr->field);
    if (fi == NULL)
	return 1;

    driver = db_start_driver_open_database(fi->driver, fi->database);
    if (driver == NULL)
	G_fatal_error(_("Unable to open database <%s> by driver <%s>"),
		      fi->database,
		      fi->driver);

    Vect_rewind(Map);
    while (1) {
	ltype = Vect_read_next_line(Map, Points, Cats);
	if (ltype == -1)
	    G_fatal_error(_("Unable to read vector map"));
	else if (ltype == -2)		/* EOF */
	    break;

	if (!(type & ltype) && !((type & GV_AREA) && (ltype & GV_CENTROID)))
	    continue;		/* used for both lines and labels */

	D_RGB_color(lattr->color.R, lattr->color.G, lattr->color.B);
	D_text_size(lattr->size, lattr->size);
	if (lattr->font)
	    D_font(lattr->font);
	if (lattr->enc)
	    D_encoding(lattr->enc);

	if (chcat) {
	    int found = 0;

	    for (i = 0; i < Cats->n_cats; i++) {
		if (Cats->field[i] == Clist->field &&
		    Vect_cat_in_cat_list(Cats->cat[i], Clist)) {
		    found = 1;
		    break;
		}
	    }
	    if (!found)
		continue;
	}
	else if (Clist->field > 0) {
	    int found = 0;

	    for (i = 0; i < Cats->n_cats; i++) {
		if (Cats->field[i] == Clist->field) {
		    found = 1;
		    break;
		}
	    }
	    /* lines with no category will be displayed */
	    if (Cats->n_cats > 0 && !found)
		continue;
	}

	if (Vect_cat_get(Cats, lattr->field, &cat)) {
	    int ncats = 0;

	    /* Read attribute from db */
	    db_free_string(&text);
	    for (i = 0; i < Cats->n_cats; i++) {
		int nrows;

		if (Cats->field[i] != lattr->field)
		    continue;
		db_init_string(&stmt);
		sprintf(buf, "select %s from %s where %s = %d", attrcol,
			fi->table, fi->key, Cats->cat[i]);
		G_debug(2, "SQL: %s", buf);
		db_append_string(&stmt, buf);

		if (db_open_select_cursor
		    (driver, &stmt, &cursor, DB_SEQUENTIAL) != DB_OK)
		    G_fatal_error(_("Unable to open select cursor: '%s'"),
				  db_get_string(&stmt));

		nrows = db_get_num_rows(&cursor);

		if (ncats > 0)
		    db_append_string(&text, "/");

		if (nrows > 0) {
		    table = db_get_cursor_table(&cursor);
		    column = db_get_table_column(table, 0);	/* first column */

		    if (db_fetch(&cursor, DB_NEXT, &more) != DB_OK)
			continue;
		    db_convert_column_value_to_string(column, &valstr);

		    db_append_string(&text, db_get_string(&valstr));
		}
		else {
		    G_warning(_("No attribute found for cat %d: %s"), cat,
			      db_get_string(&stmt));
		}

		db_close_cursor(&cursor);
		ncats++;
	    }

	    show_label_line(Points, ltype, lattr, db_get_string(&text));
	}
    }

    db_close_database_shutdown_driver(driver);
    Vect_destroy_line_struct(Points);
    Vect_destroy_cats_struct(Cats);

    return 0;
}
Пример #24
0
int main(int argc, char *argv[])
{
    int i, j, nlines, type, field, cat;
    int fd;

    /* struct Categories RCats; *//* TODO */
    struct Cell_head window;
    RASTER_MAP_TYPE out_type;
    CELL *cell;
    DCELL *dcell;
    double drow, dcol;
    char buf[2000];
    struct Option *vect_opt, *rast_opt, *field_opt, *col_opt, *where_opt;
    int Cache_size;
    struct order *cache;
    int cur_row;
    struct GModule *module;

    struct Map_info Map;
    struct line_pnts *Points;
    struct line_cats *Cats;
    int point;
    int point_cnt;		/* number of points in cache */
    int outside_cnt;		/* points outside region */
    int nocat_cnt;		/* points inside region but without category */
    int dupl_cnt;		/* duplicate categories */
    struct bound_box box;

    int *catexst, *cex;
    struct field_info *Fi;
    dbString stmt;
    dbDriver *driver;
    int select, norec_cnt, update_cnt, upderr_cnt, col_type;

    G_gisinit(argv[0]);

    module = G_define_module();
    G_add_keyword(_("vector"));
    G_add_keyword(_("raster"));
    G_add_keyword(_("position"));
    G_add_keyword(_("querying"));
    G_add_keyword(_("attribute table"));
    module->description =
	_("Uploads raster values at positions of vector points to the table.");

    vect_opt = G_define_standard_option(G_OPT_V_INPUT);
    vect_opt->key = "vector";
    vect_opt->description =
	_("Name of input vector points map for which to edit attribute table");

    rast_opt = G_define_standard_option(G_OPT_R_INPUT);
    rast_opt->key = "raster";
    rast_opt->description = _("Name of existing raster map to be queried");

    field_opt = G_define_standard_option(G_OPT_V_FIELD);

    col_opt = G_define_option();
    col_opt->key = "column";
    col_opt->type = TYPE_STRING;
    col_opt->required = YES;
    col_opt->description =
	_("Column name (will be updated by raster values)");

    where_opt = G_define_standard_option(G_OPT_DB_WHERE);

    if (G_parser(argc, argv))
	exit(EXIT_FAILURE);


    field = atoi(field_opt->answer);

    db_init_string(&stmt);
    Points = Vect_new_line_struct();
    Cats = Vect_new_cats_struct();

    G_get_window(&window);
    Vect_region_box(&window, &box);	/* T and B set to +/- PORT_DOUBLE_MAX */

    /* Open vector */
    Vect_set_open_level(2);
    Vect_open_old(&Map, vect_opt->answer, "");

    Fi = Vect_get_field(&Map, field);
    if (Fi == NULL)
	G_fatal_error(_("Database connection not defined for layer %d"),
		      field);

    /* Open driver */
    driver = db_start_driver_open_database(Fi->driver, Fi->database);
    if (driver == NULL) {
	G_fatal_error(_("Unable to open database <%s> by driver <%s>"),
		      Fi->database, Fi->driver);
    }

    /* Open raster */
    fd = Rast_open_old(rast_opt->answer, "");

    out_type = Rast_get_map_type(fd);

    /* TODO: Later possibly category labels */
    /* 
       if ( Rast_read_cats (name, "", &RCats) < 0 )
       G_fatal_error ( "Cannot read category file");
     */

    /* Check column type */
    col_type = db_column_Ctype(driver, Fi->table, col_opt->answer);

    if (col_type == -1)
	G_fatal_error(_("Column <%s> not found"), col_opt->answer);

    if (col_type != DB_C_TYPE_INT && col_type != DB_C_TYPE_DOUBLE)
	G_fatal_error(_("Column type not supported"));

    if (out_type == CELL_TYPE && col_type == DB_C_TYPE_DOUBLE)
	G_warning(_("Raster type is integer and column type is float"));

    if (out_type != CELL_TYPE && col_type == DB_C_TYPE_INT)
	G_warning(_("Raster type is float and column type is integer, some data lost!!"));

    /* Read vector points to cache */
    Cache_size = Vect_get_num_primitives(&Map, GV_POINT);
    /* Note: Some space may be wasted (outside region or no category) */

    cache = (struct order *)G_calloc(Cache_size, sizeof(struct order));

    point_cnt = outside_cnt = nocat_cnt = 0;

    nlines = Vect_get_num_lines(&Map);

    G_debug(1, "Reading %d vector features fom map", nlines);

    for (i = 1; i <= nlines; i++) {
	type = Vect_read_line(&Map, Points, Cats, i);
	G_debug(4, "line = %d type = %d", i, type);

	/* check type */
	if (!(type & GV_POINT))
	    continue;		/* Points only */

	/* check region */
	if (!Vect_point_in_box(Points->x[0], Points->y[0], 0.0, &box)) {
	    outside_cnt++;
	    continue;
	}

	Vect_cat_get(Cats, field, &cat);
	if (cat < 0) {		/* no category of given field */
	    nocat_cnt++;
	    continue;
	}

	G_debug(4, "    cat = %d", cat);

	/* Add point to cache */
	drow = Rast_northing_to_row(Points->y[0], &window);
	dcol = Rast_easting_to_col(Points->x[0], &window);

	/* a special case.
	 *   if north falls at southern edge, or east falls on eastern edge,
	 *   the point will appear outside the window.
	 *   So, for these edges, bring the point inside the window
	 */
	if (drow == window.rows)
	    drow--;
	if (dcol == window.cols)
	    dcol--;

	cache[point_cnt].row = (int)drow;
	cache[point_cnt].col = (int)dcol;
	cache[point_cnt].cat = cat;
	cache[point_cnt].count = 1;
	point_cnt++;
    }

    Vect_set_db_updated(&Map);
    Vect_hist_command(&Map);
    Vect_close(&Map);

    G_debug(1, "Read %d vector points", point_cnt);
    /* Cache may contain duplicate categories, sort by cat, find and remove duplicates 
     * and recalc count and decrease point_cnt  */
    qsort(cache, point_cnt, sizeof(struct order), by_cat);

    G_debug(1, "Points are sorted, starting duplicate removal loop");

    for (i = 0, j = 1; j < point_cnt; j++)
	if (cache[i].cat != cache[j].cat)
	    cache[++i] = cache[j];
	else
	    cache[i].count++;
    point_cnt = i + 1;

    G_debug(1, "%d vector points left after removal of duplicates",
	    point_cnt);

    /* Report number of points not used */
    if (outside_cnt)
	G_warning(_("%d points outside current region were skipped"),
		  outside_cnt);

    if (nocat_cnt)
	G_warning(_("%d points without category were skipped"), nocat_cnt);

    /* Sort cache by current region row */
    qsort(cache, point_cnt, sizeof(struct order), by_row);

    /* Allocate space for raster row */
    if (out_type == CELL_TYPE)
	cell = Rast_allocate_c_buf();
    else
	dcell = Rast_allocate_d_buf();

    /* Extract raster values from file and store in cache */
    G_debug(1, "Extracting raster values");

    cur_row = -1;

    for (point = 0; point < point_cnt; point++) {
	if (cache[point].count > 1)
	    continue;		/* duplicate cats */

	if (cur_row != cache[point].row) {
	    if (out_type == CELL_TYPE)
		Rast_get_c_row(fd, cell, cache[point].row);
	    else
		Rast_get_d_row(fd, dcell, cache[point].row);
	}
	cur_row = cache[point].row;

	if (out_type == CELL_TYPE) {
	    cache[point].value = cell[cache[point].col];
	}
	else {
	    cache[point].dvalue = dcell[cache[point].col];
	}
    }				/* point loop */

    /* Update table from cache */
    G_debug(1, "Updating db table");

    /* select existing categories to array (array is sorted) */
    select = db_select_int(driver, Fi->table, Fi->key, NULL, &catexst);

    db_begin_transaction(driver);

    norec_cnt = update_cnt = upderr_cnt = dupl_cnt = 0;

    for (point = 0; point < point_cnt; point++) {
	if (cache[point].count > 1) {
	    G_warning(_("More points (%d) of category %d, value set to 'NULL'"),
		      cache[point].count, cache[point].cat);
	    dupl_cnt++;
	}

	/* category exist in DB ? */
	cex =
	    (int *)bsearch((void *)&(cache[point].cat), catexst, select,
			   sizeof(int), srch_cat);
	if (cex == NULL) {	/* cat does not exist in DB */
	    norec_cnt++;
	    G_warning(_("No record for category %d in table <%s>"),
		      cache[point].cat, Fi->table);
	    continue;
	}

	sprintf(buf, "update %s set %s = ", Fi->table, col_opt->answer);

	db_set_string(&stmt, buf);

	if (out_type == CELL_TYPE) {
	    if (cache[point].count > 1 ||
		Rast_is_c_null_value(&cache[point].value)) {
		sprintf(buf, "NULL");
	    }
	    else {
		sprintf(buf, "%d ", cache[point].value);
	    }
	}
	else {			/* FCELL or DCELL */
	    if (cache[point].count > 1 ||
		Rast_is_d_null_value(&cache[point].dvalue)) {
		sprintf(buf, "NULL");
	    }
	    else {
		sprintf(buf, "%.10f", cache[point].dvalue);
	    }
	}
	db_append_string(&stmt, buf);

	sprintf(buf, " where %s = %d", Fi->key, cache[point].cat);
	db_append_string(&stmt, buf);
	/* user provides where condition: */
	if (where_opt->answer) {
	    sprintf(buf, " AND %s", where_opt->answer);
	    db_append_string(&stmt, buf);
	}
	G_debug(3, db_get_string(&stmt));

	/* Update table */
	if (db_execute_immediate(driver, &stmt) == DB_OK) {
	    update_cnt++;
	}
	else {
	    upderr_cnt++;
	}
    }

    G_debug(1, "Committing DB transaction");
    db_commit_transaction(driver);
    G_free(catexst);
    db_close_database_shutdown_driver(driver);
    db_free_string(&stmt);

    /* Report */
    G_message(_("%d categories loaded from table"), select);
    G_message(_("%d categories loaded from vector"), point_cnt);
    G_message(_("%d categories from vector missing in table"), norec_cnt);
    G_message(_("%d duplicate categories in vector"), dupl_cnt);
    if (!where_opt->answer)
	G_message(_("%d records updated"), update_cnt);
    G_message(_("%d update errors"), upderr_cnt);

    exit(EXIT_SUCCESS);
}
Пример #25
0
/* Returns 0 - ok , 1 - error */
int
plot(int ctype, struct Map_info *Map, int type, int field,
     char *columns, int ncols, char *sizecol, int size, double scale,
     COLOR * ocolor, COLOR * colors, int y_center, double *max_reference,
     int do3d)
{
    int ltype, nlines, line, col, more, coltype, nselcols;
    double x, y, csize, len;
    struct line_pnts *Points;
    struct line_cats *Cats;
    int cat;
    double *val;
    char buf[2000];
    struct field_info *Fi;
    dbDriver *driver;
    dbValue *value;
    dbString sql;
    dbCursor cursor;
    dbTable *table;
    dbColumn *column;

    Points = Vect_new_line_struct();
    Cats = Vect_new_cats_struct();
    db_init_string(&sql);

    Fi = Vect_get_field(Map, field);
    if (Fi == NULL)
	G_fatal_error(_("Database connection not defined for layer %d"),
		      field);

    /* Open driver */
    driver = db_start_driver_open_database(Fi->driver, Fi->database);
    if (driver == NULL) {
	G_warning(_("Unable to open database <%s> by driver <%s>"),
		  Fi->database,
		  Fi->driver);
	return 1;
    }
    db_set_error_handler_driver(driver);

    val = (double *)G_malloc((ncols + 1) * sizeof(double));	/* + 1 for sizecol */

    Vect_rewind(Map);

    nlines = Vect_get_num_lines(Map);

    /* loop through each vector feature */
    for (line = 1; line <= nlines; line++) {
	G_debug(3, "line = %d", line);
	ltype = Vect_read_line(Map, Points, Cats, line);

	if (!(ltype & type))
	    continue;

	Vect_cat_get(Cats, field, &cat);
	if (cat < 0)
	    continue;

	/* Select values from DB */
	if (ctype == CTYPE_PIE && sizecol != NULL) {
	    sprintf(buf, "select %s, %s from %s where %s = %d", columns,
		    sizecol, Fi->table, Fi->key, cat);
	    nselcols = ncols + 1;
	}
	else {
	    sprintf(buf, "select %s from %s where %s = %d", columns,
		    Fi->table, Fi->key, cat);
	    nselcols = ncols;
	}

	db_set_string(&sql, buf);
	G_debug(3, "SQL: %s", buf);

	if (db_open_select_cursor(driver, &sql, &cursor, DB_SEQUENTIAL) !=
	    DB_OK) {
	    G_warning(_("Unable to open select cursor: '%s'"),
		      buf);
	    return 1;
	}

	table = db_get_cursor_table(&cursor);
	if (db_fetch(&cursor, DB_NEXT, &more) != DB_OK || !more)
	    continue;

	for (col = 0; col < nselcols; col++) {
	    column = db_get_table_column(table, col);
	    value = db_get_column_value(column);
	    coltype = db_sqltype_to_Ctype(db_get_column_sqltype(column));
	    switch (coltype) {
	    case DB_C_TYPE_INT:
		val[col] = (double)db_get_value_int(value);
		break;
	    case DB_C_TYPE_DOUBLE:
		val[col] = db_get_value_double(value);
		break;
	    default:
		G_warning("Column type not supported (must be INT or FLOAT)");
		return 1;
	    }
	    G_debug(4, "  val[%d]: %f", col, val[col]);
	}

	db_close_cursor(&cursor);

	/* Center of chart */
	if (ltype & GV_LINES) {	/* find center */
	    len = Vect_line_length(Points) / 2;
	    Vect_point_on_line(Points, len, &x, &y, NULL, NULL, NULL);
	}
	else {
	    x = Points->x[0];
	    y = Points->y[0];
	}

	if (ctype == CTYPE_PIE) {
	    if (sizecol != NULL) {
		csize = val[ncols];
		size = scale * csize;
	    }
	    pie(x, y, size, val, ncols, ocolor, colors, do3d);
	}
	else {
	    bar(x, y, size, scale, val, ncols, ocolor, colors, y_center,
		max_reference, do3d);
	}
    }

    db_close_database_shutdown_driver(driver);
    Vect_destroy_line_struct(Points);
    Vect_destroy_cats_struct(Cats);

    return 0;
}
Пример #26
0
int area_area(struct Map_info *In, int *field, struct Map_info *Tmp,
	      struct Map_info *Out, struct field_info *Fi,
	      dbDriver * driver, int operator, int *ofield,
	      ATTRIBUTES * attr, struct ilist *BList, double snap)
{
    int ret, input, line, nlines, area, nareas;
    int in_area, in_centr, out_cat;
    struct line_pnts *Points;
    struct line_cats *Cats;
    CENTR *Centr;
    char buf[1000];
    dbString stmt;
    int nmodif;
    int verbose;

    verbose = G_verbose();

    Points = Vect_new_line_struct();
    Cats = Vect_new_cats_struct();

    /* optional snap */
    if (snap > 0) {
	int i, j, snapped_lines = 0;
	struct bound_box box;
	struct boxlist *boxlist = Vect_new_boxlist(0);
	struct ilist *reflist = Vect_new_list();
	
	G_message(_("Snapping boundaries with %g ..."), snap);

	/* snap boundaries in B to boundaries in A,
	 * not modifying boundaries in A */

	if (BList->n_values > 1)
	    qsort(BList->value, BList->n_values, sizeof(int), cmp_int);

	snapped_lines = 0;
	nlines = BList->n_values;
	for (i = 0; i < nlines; i++) {
	    line = BList->value[i];
	    Vect_read_line(Tmp, Points, Cats, line);
	    /* select lines by box */
	    Vect_get_line_box(Tmp, line, &box);
	    box.E += snap;
	    box.W -= snap;
	    box.N += snap;
	    box.S -= snap;
	    box.T = 0.0;
	    box.B = 0.0;
	    Vect_select_lines_by_box(Tmp, &box, GV_BOUNDARY, boxlist);
	    
	    if (boxlist->n_values > 0) {
		Vect_reset_list(reflist);
		for (j = 0; j < boxlist->n_values; j++) {
		    int aline = boxlist->id[j];

		    if (!bsearch(&aline, BList->value, BList->n_values,
			sizeof(int), cmp_int)) {
			G_ilist_add(reflist, aline);
		    }
		}
		
		/* snap bline to alines */
		if (Vect_snap_line(Tmp, reflist, Points, snap, 0, NULL, NULL)) {
		    /* rewrite bline*/
		    Vect_delete_line(Tmp, line);
		    ret = Vect_write_line(Tmp, GV_BOUNDARY, Points, Cats);
		    G_ilist_add(BList, ret);
		    snapped_lines++;
		    G_debug(3, "line %d snapped", line);
		}
	    }
	}
	Vect_destroy_boxlist(boxlist);
	Vect_destroy_list(reflist);

	G_verbose_message(n_("%d boundary snapped",
                             "%d boundaries snapped",
                             snapped_lines), snapped_lines);
    }

    /* same procedure like for v.in.ogr:
     * Vect_clean_small_angles_at_nodes() can change the geometry so that new intersections
     * are created. We must call Vect_break_lines(), Vect_remove_duplicates()
     * and Vect_clean_small_angles_at_nodes() until no more small dangles are found */
    do {
	G_message(_("Breaking lines..."));
	Vect_break_lines_list(Tmp, NULL, BList, GV_BOUNDARY, NULL);

	/* Probably not necessary for LINE x AREA */
	G_message(_("Removing duplicates..."));
	Vect_remove_duplicates(Tmp, GV_BOUNDARY, NULL);

	G_message(_("Cleaning boundaries at nodes..."));
	nmodif =
	    Vect_clean_small_angles_at_nodes(Tmp, GV_BOUNDARY, NULL);
    } while (nmodif > 0);

    /* ?: May be result of Vect_break_lines() + Vect_remove_duplicates() any dangle or bridge?
     * In that case, calls to Vect_remove_dangles() and Vect_remove_bridges() would be also necessary */

    G_set_verbose(0);
    /* should be fast, be silent */
    Vect_build_partial(Tmp, GV_BUILD_AREAS);
    G_set_verbose(verbose);
    nlines = Vect_get_num_lines(Tmp);
    ret = 0;
    for (line = 1; line <= nlines; line++) {
	if (!Vect_line_alive(Tmp, line))
	    continue;
	if (Vect_get_line_type(Tmp, line) == GV_BOUNDARY) {
	    int left, rite;
	    
	    Vect_get_line_areas(Tmp, line, &left, &rite);
	    
	    if (left == 0 || rite == 0) {
		/* invalid boundary */
		ret = 1;
		break;
	    }
	}
    }
    if (ret) {
	Vect_remove_dangles(Tmp, GV_BOUNDARY, -1, NULL);
	Vect_remove_bridges(Tmp, NULL, NULL, NULL);
    }

    G_set_verbose(0);
    Vect_build_partial(Tmp, GV_BUILD_NONE);
    Vect_build_partial(Tmp, GV_BUILD_BASE);
    G_set_verbose(verbose);
    G_message(_("Merging lines..."));
    Vect_merge_lines(Tmp, GV_BOUNDARY, NULL, NULL);

    /* Attach islands */
    G_message(_("Attaching islands..."));
    /* can take some time, show messages */
    Vect_build_partial(Tmp, GV_BUILD_ATTACH_ISLES);

    /* Calculate new centroids for all areas */
    nareas = Vect_get_num_areas(Tmp);

    Centr = (CENTR *) G_malloc((nareas + 1) * sizeof(CENTR));	/* index from 1 ! */
    for (area = 1; area <= nareas; area++) {
	ret =
	    Vect_get_point_in_area(Tmp, area, &(Centr[area].x),
				   &(Centr[area].y));
	if (ret < 0) {
	    G_warning(_("Cannot calculate area centroid"));
	    Centr[area].valid = 0;
	}
	else {
	    Centr[area].valid = 1;
	}
    }

    /* Query input maps */
    for (input = 0; input < 2; input++) {
	G_message(_("Querying vector map <%s>..."),
		  Vect_get_full_name(&(In[input])));

	for (area = 1; area <= nareas; area++) {
	    Centr[area].cat[input] = Vect_new_cats_struct();

	    G_percent(area, nareas, 1);

	    in_area =
		Vect_find_area(&(In[input]), Centr[area].x, Centr[area].y);
	    if (in_area > 0) {
		in_centr = Vect_get_area_centroid(&(In[input]), in_area);
		if (in_centr > 0) {
		    int i;

		    Vect_read_line(&(In[input]), NULL, Cats, in_centr);
		    /* Add all cats with original field number */
		    for (i = 0; i < Cats->n_cats; i++) {
			if (Cats->field[i] == field[input]) {
			    ATTR *at;

			    Vect_cat_set(Centr[area].cat[input], ofield[input + 1],
					 Cats->cat[i]);

			    /* Mark as used */
			    at = find_attr(&(attr[input]), Cats->cat[i]);
			    if (!at)
				G_fatal_error(_("Attribute not found"));

			    at->used = 1;
			}
		    }
		}
	    }
	}
    }

    G_message(_("Writing centroids..."));

    db_init_string(&stmt);
    out_cat = 1;
    for (area = 1; area <= nareas; area++) {
	int i;

	G_percent(area, nareas, 1);

	/* check the condition */
	switch (operator) {
	case OP_AND:
	    if (!
		(Centr[area].cat[0]->n_cats > 0 &&
		 Centr[area].cat[1]->n_cats > 0))
		continue;
	    break;
	case OP_OR:
	    if (!
		(Centr[area].cat[0]->n_cats > 0 ||
		 Centr[area].cat[1]->n_cats > 0))
		continue;
	    break;
	case OP_NOT:
	    if (!
		(Centr[area].cat[0]->n_cats > 0 &&
		 !(Centr[area].cat[1]->n_cats > 0)))
		continue;
	    break;
	case OP_XOR:
	    if ((Centr[area].cat[0]->n_cats > 0 &&
		 Centr[area].cat[1]->n_cats > 0) ||
		(!(Centr[area].cat[0]->n_cats > 0) &&
		 !(Centr[area].cat[1]->n_cats > 0)))
		continue;
	    break;
	}

	Vect_reset_line(Points);
	Vect_reset_cats(Cats);

	Vect_append_point(Points, Centr[area].x, Centr[area].y, 0.0);

	if (ofield[0] > 0) {
	    /* Add new cats for all combinations of input cats (-1 in cycle for null) */
	    for (i = -1; i < Centr[area].cat[0]->n_cats; i++) {
		int j;

		if (i == -1 && Centr[area].cat[0]->n_cats > 0)
		    continue;	/* no need to make null */

		for (j = -1; j < Centr[area].cat[1]->n_cats; j++) {
		    if (j == -1 && Centr[area].cat[1]->n_cats > 0)
			continue;	/* no need to make null */

		    if (ofield[0] > 0)
			Vect_cat_set(Cats, ofield[0], out_cat);

		    /* attributes */
		    if (driver) {
			ATTR *at;

			sprintf(buf, "insert into %s values ( %d", Fi->table,
				out_cat);
			db_set_string(&stmt, buf);

			/* cata */
			if (i >= 0) {
			    if (attr[0].columns) {
				at = find_attr(&(attr[0]),
					       Centr[area].cat[0]->cat[i]);
				if (!at)
				    G_fatal_error(_("Attribute not found"));

				if (at->values)
				    db_append_string(&stmt, at->values);
				else
				    db_append_string(&stmt, attr[0].null_values);
			    }
			    else {
				sprintf(buf, ", %d", Centr[area].cat[0]->cat[i]);
				db_append_string(&stmt, buf);
			    }
			}
			else {
			    if (attr[0].columns) {
				db_append_string(&stmt, attr[0].null_values);
			    }
			    else {
				sprintf(buf, ", null");
				db_append_string(&stmt, buf);
			    }
			}

			/* catb */
			if (j >= 0) {
			    if (attr[1].columns) {
				at = find_attr(&(attr[1]),
					       Centr[area].cat[1]->cat[j]);
				if (!at)
				    G_fatal_error(_("Attribute not found"));

				if (at->values)
				    db_append_string(&stmt, at->values);
				else
				    db_append_string(&stmt, attr[1].null_values);
			    }
			    else {
				sprintf(buf, ", %d", Centr[area].cat[1]->cat[j]);
				db_append_string(&stmt, buf);
			    }
			}
			else {
			    if (attr[1].columns) {
				db_append_string(&stmt, attr[1].null_values);
			    }
			    else {
				sprintf(buf, ", null");
				db_append_string(&stmt, buf);
			    }
			}

			db_append_string(&stmt, " )");

			G_debug(3, "%s", db_get_string(&stmt));

			if (db_execute_immediate(driver, &stmt) != DB_OK)
			    G_warning(_("Unable to insert new record: '%s'"),
				      db_get_string(&stmt));
		    }
		    out_cat++;
		}
	    }
	}

	/* Add all cats from input vectors */
	if (ofield[1] > 0 && field[0] > 0) {
	    for (i = 0; i < Centr[area].cat[0]->n_cats; i++) {
		if (Centr[area].cat[0]->field[i] == field[0])
		    Vect_cat_set(Cats, ofield[1], Centr[area].cat[0]->cat[i]);
	    }
	}

	if (ofield[2] > 0 && field[1] > 0 && ofield[1] != ofield[2]) {
	    for (i = 0; i < Centr[area].cat[1]->n_cats; i++) {
		if (Centr[area].cat[1]->field[i] == field[1])
		    Vect_cat_set(Cats, ofield[2], Centr[area].cat[1]->cat[i]);
	    }
	}

	Vect_write_line(Tmp, GV_CENTROID, Points, Cats);
	Vect_write_line(Out, GV_CENTROID, Points, Cats);
    }

    G_set_verbose(0);
    /* should be fast, be silent */
    Vect_build_partial(Tmp, GV_BUILD_CENTROIDS);
    G_set_verbose(verbose);
    /* Copy valid boundaries to final output */
    nlines = Vect_get_num_lines(Tmp);

    for (line = 1; line <= nlines; line++) {
	int i, ltype, side[2], centr[2];

	G_percent(line, nlines, 1);	/* must be before any continue */

	if (!Vect_line_alive(Tmp, line))
	    continue;

	ltype = Vect_read_line(Tmp, Points, Cats, line);
	if (!(ltype & GV_BOUNDARY))
	    continue;

	Vect_get_line_areas(Tmp, line, &side[0], &side[1]);

	for (i = 0; i < 2; i++) {
	    if (side[i] == 0) {	/* This should not happen ! */
		centr[i] = 0;
		continue;
	    }

	    if (side[i] > 0) {
		area = side[i];
	    }
	    else {		/* island */
		area = Vect_get_isle_area(Tmp, abs(side[i]));
	    }

	    if (area > 0)
		centr[i] = Vect_get_area_centroid(Tmp, area);
	    else
		centr[i] = 0;
	}

	if (centr[0] || centr[1])
	    Vect_write_line(Out, GV_BOUNDARY, Points, Cats);
    }

    return 0;
}
Пример #27
0
int update(struct Map_info *Map)
{
    int i, *catexst, *cex, upd, fcat;
    char buf1[2000], buf2[2000], left[20], right[20];
    struct field_info *qFi, *Fi;
    dbString stmt;
    dbDriver *driver;

    vstat.dupl = 0;
    vstat.exist = 0;
    vstat.notexist = 0;
    vstat.update = 0;
    vstat.error = 0;

    db_init_string(&stmt);

    /* layer to find table to read from */
    qFi = Vect_get_field(Map, options.qfield);
    if (options.option == O_QUERY && qFi == NULL)
        G_fatal_error(_("Database connection not defined for layer %d. Use v.db.connect first."),
                      options.qfield);
    /* layer to find table to write to */
    if ((Fi = Vect_get_field(Map, options.field)) == NULL)
	G_fatal_error(_("Database connection not defined for layer %d. Use v.db.connect first."),
		      options.field);
    if (qFi) {
      G_debug(3, "Reading from map <%s>, query layer %d (table <%s>): updating table <%s>, column <%s>", 
	      options.name, options.qfield, qFi->table, Fi->table, Fi->key);
    }
    else {
      G_debug(3, "Reading from map <%s>, updating table <%s>, column <%s>", 
	      options.name, Fi->table, Fi->key);
    }

    /* Open driver */
    driver = db_start_driver_open_database(Fi->driver, Fi->database);
    if (driver == NULL) {
	G_fatal_error(_("Unable to open database <%s> by driver <%s>"),
		      Fi->database, Fi->driver);
    }
    db_set_error_handler_driver(driver);

    db_begin_transaction(driver);

    /* select existing categories (layer) to array (array is sorted) */
    vstat.select = db_select_int(driver, Fi->table, Fi->key, NULL, &catexst);
    G_debug(3, "Existing categories: %d", vstat.select);
    
    /* create beginning of stmt */
    switch (options.option) {
    case O_CAT:
	sprintf(buf1, "insert into %s ( %s ) values ", Fi->table, Fi->key);
	break;
    case O_COUNT:
    case O_LENGTH:
    case O_AREA:
    case O_QUERY:
    case O_COMPACT:
    case O_FD:
    case O_PERIMETER:
    case O_SLOPE:
    case O_SINUOUS:
    case O_AZIMUTH:
	sprintf(buf1, "update %s set %s =", Fi->table, options.col[0]);
	break;
    case O_COOR:
    case O_START:
    case O_END:
    case O_SIDES:
	sprintf(buf1, "update %s set ", Fi->table);
	break;
    }

    /* update */
    G_message(_("Updating database..."));
    for (i = 0; i < vstat.rcat; i++) {
	G_percent(i, vstat.rcat, 2);

	fcat = Values[i].cat;	
	if (fcat < 0)
	    continue;
	switch (options.option) {
	case O_CAT:
	    sprintf(buf2, "%s ( %d )", buf1, Values[i].cat);
	    break;

	case O_COUNT:
	    sprintf(buf2, "%s %d where %s = %d", buf1, Values[i].count1,
		    Fi->key, Values[i].cat);
	    break;

	case O_LENGTH:
	case O_AREA:
	case O_COMPACT:
	case O_FD:
	case O_PERIMETER:
	case O_SLOPE:
	case O_SINUOUS:
	case O_AZIMUTH:
	    sprintf(buf2, "%s %f where %s = %d", buf1, Values[i].d1, Fi->key,
		    Values[i].cat);
	    break;

	case O_COOR:
	case O_START:
	case O_END:
	    if (Values[i].count1 > 1) {
		G_warning(_("More elements of category %d, nothing loaded to database"),
			  Values[i].cat);
		vstat.dupl++;
		continue;
	    }
	    if (Values[i].count1 < 1) {	/* No points */
		continue;
	    }
	    if (options.col[2]) {
		sprintf(buf2,
			"%s %s = %.15g, %s = %.15g, %s = %.15g where %s = %d",
			buf1, options.col[0], Values[i].d1, options.col[1],
			Values[i].d2, options.col[2], Values[i].d3, Fi->key,
			Values[i].cat);
	    }
	    else {
		sprintf(buf2, "%s %s = %.15g, %s = %.15g  where %s = %d",
			buf1, options.col[0], Values[i].d1, options.col[1],
			Values[i].d2, Fi->key, Values[i].cat);
	    }
	    break;

	case O_SIDES:
	    if (Values[i].count1 == 1) {
		if (Values[i].i1 >= 0)
		    sprintf(left, "%d", Values[i].i1);
		else
		    sprintf(left, "-1");	/* NULL, no area/cat */
	    }
	    else if (Values[i].count1 > 1) {
		sprintf(left, "null");
	    }
	    else {		/* Values[i].count1 == 0 */
		/* It can be OK if the category is assigned to an element
		   type which is not GV_BOUNDARY */
		/* -> TODO: print only if there is boundary with that cat */
		sprintf(left, "null");
	    }

	    if (Values[i].count2 == 1) {
		if (Values[i].i2 >= 0)
		    sprintf(right, "%d", Values[i].i2);
		else
		    sprintf(right, "-1");	/* NULL, no area/cat */
	    }
	    else if (Values[i].count2 > 1) {
		sprintf(right, "null");
	    }
	    else {		/* Values[i].count1 == 0 */
		sprintf(right, "null");
	    }

	    sprintf(buf2, "%s %s = %s, %s = %s  where %s = %d", buf1,
		    options.col[0], left, options.col[1], right, Fi->key,
		    Values[i].cat);

	    break;

	case O_QUERY:
	    if (Values[i].null) {
		sprintf(buf2, "%s null where %s = %d", buf1, Fi->key,
			Values[i].cat);
	    }
	    else {
		switch (vstat.qtype) {
		case (DB_C_TYPE_INT):
		    sprintf(buf2, "%s %d where %s = %d", buf1, Values[i].i1,
			    Fi->key, Values[i].cat);
		    break;
		case (DB_C_TYPE_DOUBLE):
		    sprintf(buf2, "%s %f where %s = %d", buf1, Values[i].d1,
			    Fi->key, Values[i].cat);
		    break;
		case (DB_C_TYPE_STRING):
		    sprintf(buf2, "%s '%s' where %s = %d", buf1,
			    Values[i].str1, Fi->key, Values[i].cat);
		    break;
		case (DB_C_TYPE_DATETIME):
		    sprintf(buf2, "%s '%s' where %s = %d", buf1,
			    Values[i].str1, Fi->key, Values[i].cat);
		    break;
		}
	    }
	}

	G_debug(3, "SQL: %s", buf2);
	db_set_string(&stmt, buf2);

	/* category exist in DB table ? */
	cex = (int *)bsearch((void *)&fcat, catexst, vstat.select, sizeof(int),
			     srch);
	
	if (options.option == O_CAT) {
	    if (cex == NULL) {	/* cat does not exist in DB */
		upd = 1;
		vstat.notexist++;
	    }
	    else {		/* cat exists in DB */
		G_warning(_("Record (cat %d) already exists (not inserted)"),
			  fcat);
		upd = 0;
		vstat.exist++;
	    }
	}
	else {
	    if (cex == NULL) {	/* cat does not exist in DB */
		G_warning(_("Record (cat %d) does not exist (not updated)"),
			  fcat);
		upd = 0;
		vstat.notexist++;
	    }
	    else {		/* cat exists in DB */
		upd = 1;
		vstat.exist++;
	    }
	}

	if (upd == 1) {
	    if (options.sql) {
		fprintf(stdout, "%s\n", db_get_string(&stmt));
	    }
	    else {
		if (db_execute_immediate(driver, &stmt) == DB_OK) {
		    vstat.update++;
		}
		else {
		    vstat.error++;
		}
	    }
	}
    }
    G_percent(1, 1, 1);

    db_commit_transaction(driver);

    G_free(catexst);
    
    db_close_database_shutdown_driver(driver);
    db_free_string(&stmt);

    return 0;
}
Пример #28
0
Файл: main.c Проект: caomw/grass
int main(int argc, char *argv[])
{
    int i, cat, with_z, more, ctype, nrows;
    char buf[DB_SQL_MAX];
    int count;
    double coor[3];
    int ncoor;
    struct Option *driver_opt, *database_opt, *table_opt;
    struct Option *xcol_opt, *ycol_opt, *zcol_opt, *keycol_opt, *where_opt,
	*outvect;
    struct Flag *same_table_flag;
    struct GModule *module;
    struct Map_info Map;
    struct line_pnts *Points;
    struct line_cats *Cats;
    dbString sql;
    dbDriver *driver;
    dbCursor cursor;
    dbTable *table;
    dbColumn *column;
    dbValue *value;
    struct field_info *fi;

    G_gisinit(argv[0]);

    module = G_define_module();
    G_add_keyword(_("vector"));
    G_add_keyword(_("import"));
    G_add_keyword(_("database"));
    G_add_keyword(_("points"));
    module->description =
	_("Creates new vector (points) map from database table containing coordinates.");

    table_opt = G_define_standard_option(G_OPT_DB_TABLE);
    table_opt->required = YES;
    table_opt->description = _("Input table name");

    driver_opt = G_define_standard_option(G_OPT_DB_DRIVER);
    driver_opt->options = db_list_drivers();
    driver_opt->answer = (char *)db_get_default_driver_name();
    driver_opt->guisection = _("Input DB");

    database_opt = G_define_standard_option(G_OPT_DB_DATABASE);
    database_opt->answer = (char *)db_get_default_database_name();
    database_opt->guisection = _("Input DB");

    xcol_opt = G_define_standard_option(G_OPT_DB_COLUMN);
    xcol_opt->key = "x";
    xcol_opt->required = YES;
    xcol_opt->description = _("Name of column containing x coordinate");

    ycol_opt = G_define_standard_option(G_OPT_DB_COLUMN);
    ycol_opt->key = "y";
    ycol_opt->required = YES;
    ycol_opt->description = _("Name of column containing y coordinate");

    zcol_opt = G_define_standard_option(G_OPT_DB_COLUMN);
    zcol_opt->key = "z";
    zcol_opt->description = _("Name of column containing z coordinate");
    zcol_opt->guisection = _("3D output");

    keycol_opt = G_define_standard_option(G_OPT_DB_COLUMN);
    keycol_opt->key = "key";
    keycol_opt->required = NO;
    keycol_opt->label = _("Name of column containing category number");
    keycol_opt->description = _("Must refer to an integer column");

    where_opt = G_define_standard_option(G_OPT_DB_WHERE);
    where_opt->guisection = _("Selection");

    outvect = G_define_standard_option(G_OPT_V_OUTPUT);

    same_table_flag = G_define_flag();
    same_table_flag->key = 't';
    same_table_flag->description =
	_("Use imported table as attribute table for new map");

    if (G_parser(argc, argv))
	exit(EXIT_FAILURE);

    if (zcol_opt->answer) {
	with_z = WITH_Z;
	ncoor = 3;
    }
    else {
	with_z = WITHOUT_Z;
	ncoor = 2;
    }

    Points = Vect_new_line_struct();
    Cats = Vect_new_cats_struct();
    db_init_string(&sql);

    if (G_get_overwrite()) {
	/* We don't want to delete the input table when overwriting the output
	 * vector. */
	char name[GNAME_MAX], mapset[GMAPSET_MAX];

	if (!G_name_is_fully_qualified(outvect->answer, name, mapset)) {
	    strcpy(name, outvect->answer);
	    strcpy(mapset, G_mapset());
	}

	Vect_set_open_level(1); /* no topo needed */

	if (strcmp(mapset, G_mapset()) == 0 && G_find_vector2(name, mapset) &&
	    Vect_open_old(&Map, name, mapset) >= 0) {
	    int num_dblinks;

	    num_dblinks = Vect_get_num_dblinks(&Map);
	    for (i = 0; i < num_dblinks; i++) {
		if ((fi = Vect_get_dblink(&Map, i)) != NULL &&
		    strcmp(fi->driver, driver_opt->answer) == 0 &&
		    strcmp(fi->database, database_opt->answer) == 0 &&
		    strcmp(fi->table, table_opt->answer) == 0)
		    G_fatal_error(_("Vector map <%s> cannot be overwritten "
				    "because input table <%s> is linked to "
				    "this map."),
				    outvect->answer, table_opt->answer);
	    }
	    Vect_close(&Map);
	}
    }

    if (Vect_open_new(&Map, outvect->answer, with_z) < 0)
	G_fatal_error(_("Unable to create vector map <%s>"),
			outvect->answer);

    Vect_set_error_handler_io(NULL, &Map);
    
    Vect_hist_command(&Map);

    fi = Vect_default_field_info(&Map, 1, NULL, GV_1TABLE);

    /* Open driver */
    driver = db_start_driver_open_database(driver_opt->answer,
					   database_opt->answer);
    if (driver == NULL) {
	G_fatal_error(_("Unable to open database <%s> by driver <%s>"),
		      fi->database, fi->driver);
    }
    db_set_error_handler_driver(driver);
    
    /* check if target table already exists */
    G_debug(3, "Output vector table <%s>, driver: <%s>, database: <%s>",
	    outvect->answer, db_get_default_driver_name(),
	    db_get_default_database_name());

    if (!same_table_flag->answer &&
	db_table_exists(db_get_default_driver_name(),
			db_get_default_database_name(), outvect->answer) == 1)
	G_fatal_error(_("Output vector map, table <%s> (driver: <%s>, database: <%s>) "
		       "already exists"), outvect->answer,
		      db_get_default_driver_name(),
		      db_get_default_database_name());

    if (keycol_opt->answer) {
        int coltype;
        coltype = db_column_Ctype(driver, table_opt->answer, keycol_opt->answer);

        if (coltype == -1)
            G_fatal_error(_("Column <%s> not found in table <%s>"),
                          keycol_opt->answer, table_opt->answer);
        if (coltype != DB_C_TYPE_INT)
            G_fatal_error(_("Data type of key column must be integer"));
    }
    else {
        if (same_table_flag->answer) {
            G_fatal_error(_("Option <%s> must be specified when -%c flag is given"),
                          keycol_opt->key, same_table_flag->key);
        }

        if (strcmp(db_get_default_driver_name(), "sqlite") != 0)
            G_fatal_error(_("Unable to define key column. This operation is not supported "
                            "by <%s> driver. You need to define <%s> option."),
                          fi->driver, keycol_opt->key);
    }

    /* Open select cursor */
    sprintf(buf, "SELECT %s, %s", xcol_opt->answer, ycol_opt->answer);
    db_set_string(&sql, buf);
    if (with_z) {
	sprintf(buf, ", %s", zcol_opt->answer);
	db_append_string(&sql, buf);
    }
    if (keycol_opt->answer) {
	sprintf(buf, ", %s", keycol_opt->answer);
	db_append_string(&sql, buf);
    }
    sprintf(buf, " FROM %s", table_opt->answer);
    db_append_string(&sql, buf);
    
    if (where_opt->answer) {
	sprintf(buf, " WHERE %s", where_opt->answer);
	db_append_string(&sql, buf);
    }
    G_debug(2, "SQL: %s", db_get_string(&sql));

    if (db_open_select_cursor(driver, &sql, &cursor, DB_SEQUENTIAL) != DB_OK) {
	G_fatal_error(_("Unable to open select cursor: '%s'"),
		      db_get_string(&sql));
    }

    table = db_get_cursor_table(&cursor);
    nrows = db_get_num_rows(&cursor);

    G_debug(2, "%d points selected", nrows);

    count = cat = 0;
    G_message(_("Writing features..."));
    while (db_fetch(&cursor, DB_NEXT, &more) == DB_OK && more) {
	G_percent(count, nrows, 2);
	/* key column */
        if (keycol_opt->answer) {
            column = db_get_table_column(table, with_z ? 3 : 2);
            ctype = db_sqltype_to_Ctype(db_get_column_sqltype(column));
            if (ctype != DB_C_TYPE_INT)
                G_fatal_error(_("Key column must be integer"));
            value = db_get_column_value(column);
            cat = db_get_value_int(value);
        }
        else {
            cat++;
        }

        /* coordinates */
	for (i = 0; i < ncoor; i++) {
	    column = db_get_table_column(table, i);
	    ctype = db_sqltype_to_Ctype(db_get_column_sqltype(column));
	    if (ctype != DB_C_TYPE_INT && ctype != DB_C_TYPE_DOUBLE)
		G_fatal_error(_("x/y/z column must be integer or double"));
	    value = db_get_column_value(column);
	    if (ctype == DB_C_TYPE_INT)
		coor[i] = (double)db_get_value_int(value);
	    else
		coor[i] = db_get_value_double(value);
	}

	Vect_reset_line(Points);
	Vect_reset_cats(Cats);

	Vect_append_point(Points, coor[0], coor[1], coor[2]);

	Vect_cat_set(Cats, 1, cat);

	Vect_write_line(&Map, GV_POINT, Points, Cats);

	count++;
    }
    G_percent(1, 1, 1);

    /* close connection to input DB before copying attributes */
    db_close_database_shutdown_driver(driver);

    /* Copy table */
    if (!same_table_flag->answer) {
        G_message(_("Copying attributes..."));
        
        if (DB_FAILED == db_copy_table_where(driver_opt->answer, database_opt->answer,
                                             table_opt->answer,
                                             fi->driver, fi->database, fi->table,
                                             where_opt->answer)) { /* where can be NULL */
            G_warning(_("Unable to copy table"));
	}
	else {
	    Vect_map_add_dblink(&Map, 1, NULL, fi->table,
                                keycol_opt->answer ? keycol_opt->answer : GV_KEY_COLUMN,
				fi->database, fi->driver);
	}

        if (!keycol_opt->answer) {
            /* TODO: implement for all DB drivers in generic way if
             * possible */
            
            driver = db_start_driver_open_database(fi->driver, fi->database);
            if (driver == NULL) {
                G_fatal_error(_("Unable to open database <%s> by driver <%s>"),
                              fi->database, fi->driver);
            }
            db_set_error_handler_driver(driver);

            /* add key column */
            sprintf(buf, "ALTER TABLE %s ADD COLUMN %s INTEGER",
                    fi->table, GV_KEY_COLUMN);
            db_set_string(&sql, buf);
            
            if (db_execute_immediate(driver, &sql) != DB_OK) {
                G_fatal_error(_("Unable to add key column <%s>: "
                                "SERIAL type is not supported by <%s>"), 
                              GV_KEY_COLUMN, fi->driver);
            }

            /* update key column */
            sprintf(buf, "UPDATE %s SET %s = _ROWID_",
                    fi->table, GV_KEY_COLUMN);
            db_set_string(&sql, buf);
            
            if (db_execute_immediate(driver, &sql) != DB_OK) {
                G_fatal_error(_("Failed to update key column <%s>"),
                              GV_KEY_COLUMN);
            }

        }
    }
    else {
        /* do not copy attributes, link original table */
	Vect_map_add_dblink(&Map, 1, NULL, table_opt->answer,
                            keycol_opt->answer ? keycol_opt->answer : GV_KEY_COLUMN,
                            database_opt->answer, driver_opt->answer);
    }

    Vect_build(&Map);
    Vect_close(&Map);

    G_done_msg(_n("%d point written to vector map.",
                  "%d points written to vector map.",
                  count), count);

    return (EXIT_SUCCESS);
}
Пример #29
0
int line_area(struct Map_info *In, int *field, struct Map_info *Tmp,
	      struct Map_info *Out, struct field_info *Fi,
	      dbDriver * driver, int operator, int *ofield,
	      ATTRIBUTES * attr, struct ilist *BList)
{
    int line, nlines, ncat;
    struct line_pnts *Points;
    struct line_cats *Cats, *ACats, *OCats;

    char buf[1000];
    dbString stmt;

    Points = Vect_new_line_struct();
    Cats = Vect_new_cats_struct();
    ACats = Vect_new_cats_struct();
    OCats = Vect_new_cats_struct();
    db_init_string(&stmt);

    G_message(_("Breaking lines..."));
    Vect_break_lines_list(Tmp, NULL, BList, GV_LINE | GV_BOUNDARY, NULL);

    /*
    G_message(_("Merging lines..."));
    Vect_merge_lines(Tmp, GV_LINE, NULL, NULL);
    */

    nlines = Vect_get_num_lines(Tmp);

    /* Warning!: cleaning process (break) creates new vertices which are usually slightly 
     * moved (RE), to compare such new vertex with original input is a problem?
     * 
     * TODO?: would it be better to copy centroids also and query output map? 
     */

    /* Check if the line is inside or outside binput area */
    G_message(_("Selecting lines..."));
    ncat = 1;
    for (line = 1; line <= nlines; line++) {
	int ltype;

	G_percent(line, nlines, 1);	/* must be before any continue */

	if (!Vect_line_alive(Tmp, line))
	    continue;

	ltype = Vect_get_line_type(Tmp, line);

	if (ltype == GV_BOUNDARY) {	/* No more needed */
	    continue;
	}

	/* Now the type should be only GV_LINE */

	/* Decide if the line is inside or outside the area. In theory:
	 * 1) All vertices outside
	 *      - easy, first vertex must be outside
	 * 2) All vertices inside 
	 * 3) All vertices on the boundary, we take it as inside (attention, 
	 *    result of Vect_point_in_area() for points on segments between vertices may be both
	 *    inside or outside, because of representation of numbers)
	 * 4) One or two end vertices on the boundary, all others outside
	 * 5) One or two end vertices on the boundary, all others inside 
	 *
	 */

	/* Note/TODO: the test done is quite simple, check the point in the middle of segment.
	 * If the line overlaps the boundary, the result may be both outside and inside
	 * this should be solved (check angles?)
	 * This should not happen if Vect_break_lines_list() works correctly
	 */

	/* merge here */
	merge_line(Tmp, line, Points, Cats);

	G_debug(3, "line = %d", line);

	point_area(&(In[1]), field[1], (Points->x[0] + Points->x[1]) / 2,
		   (Points->y[0] + Points->y[1]) / 2, ACats);

	if ((ACats->n_cats > 0 && operator == OP_AND) ||
	    (ACats->n_cats == 0 && operator == OP_NOT)) {
	    int i;

	    /* Point is inside */
	    G_debug(3, "OK, write line, line ncats = %d area ncats = %d",
		    Cats->n_cats, ACats->n_cats);

	    Vect_reset_cats(OCats);

	    if (ofield[0]  > 0) {
		/* rewrite with all combinations of acat - bcat (-1 in cycle for null) */
		for (i = -1; i < Cats->n_cats; i++) {	/* line cats */
		    int j;

		    if (i == -1 && Cats->n_cats > 0)
			continue;	/* no need to make null */

		    for (j = -1; j < ACats->n_cats; j++) {
			if (j == -1 && ACats->n_cats > 0)
			    continue;	/* no need to make null */

			if (ofield[0] > 0)
			    Vect_cat_set(OCats, ofield[0], ncat);

			/* Attributes */
			if (driver) {
			    ATTR *at;

			    sprintf(buf, "insert into %s values ( %d", Fi->table,
				    ncat);
			    db_set_string(&stmt, buf);

			    /* cata */
			    if (i >= 0) {
				if (attr[0].columns) {
				    at = find_attr(&(attr[0]), Cats->cat[i]);
				    if (!at)
					G_fatal_error(_("Attribute not found"));

				    if (at->values)
					db_append_string(&stmt, at->values);
				    else
					db_append_string(&stmt,
							 attr[0].null_values);
				}
				else {
				    sprintf(buf, ", %d", Cats->cat[i]);
				    db_append_string(&stmt, buf);
				}
			    }
			    else {
				if (attr[0].columns) {
				    db_append_string(&stmt, attr[0].null_values);
				}
				else {
				    sprintf(buf, ", null");
				    db_append_string(&stmt, buf);
				}
			    }

			    /* catb */
			    if (j >= 0) {
				if (attr[1].columns) {
				    at = find_attr(&(attr[1]), ACats->cat[j]);
				    if (!at)
					G_fatal_error(_("Attribute not found"));

				    if (at->values)
					db_append_string(&stmt, at->values);
				    else
					db_append_string(&stmt,
							 attr[1].null_values);
				}
				else {
				    sprintf(buf, ", %d", ACats->cat[j]);
				    db_append_string(&stmt, buf);
				}
			    }
			    else {
				if (attr[1].columns) {
				    db_append_string(&stmt, attr[1].null_values);
				}
				else {
				    sprintf(buf, ", null");
				    db_append_string(&stmt, buf);
				}
			    }

			    db_append_string(&stmt, " )");

			    G_debug(3, "%s", db_get_string(&stmt));

			    if (db_execute_immediate(driver, &stmt) != DB_OK)
				G_warning(_("Unable to insert new record: '%s'"),
					  db_get_string(&stmt));
			}

			ncat++;
		    }
		}
	    }

	    /* Add cats from input vectors */
	    if (ofield[1] > 0 && field[0] > 0) {
		for (i = 0; i < Cats->n_cats; i++) {
		    if (Cats->field[i] == field[0])
			Vect_cat_set(OCats, ofield[1], Cats->cat[i]);
		}
	    }

	    if (ofield[2] > 0 && field[1] > 0 && ofield[1] != ofield[2]) {
		for (i = 0; i < ACats->n_cats; i++) {
		    if (ACats->field[i] == field[1])
			Vect_cat_set(OCats, ofield[2], ACats->cat[i]);
		}
	    }

	    Vect_write_line(Out, ltype, Points, OCats);
	}
    }

    return 0;
}
Пример #30
0
int main(int argc, char *argv[])
{
    struct Map_info In, Out;
    static struct line_pnts *Points;
    struct line_cats *Cats;
    struct GModule *module;	/* GRASS module for parsing arguments */
    struct Option *map_in, *map_out;
    struct Option *cat_opt, *field_opt, *where_opt, *abcol, *afcol;
    struct Option *iter_opt, *error_opt;
    struct Flag *geo_f, *add_f;
    int chcat, with_z;
    int layer, mask_type;
    struct varray *varray;
    dglGraph_s *graph;
    int i, geo, nnodes, nlines, j, max_cat;
    char buf[2000], *covered;

    /* initialize GIS environment */
    G_gisinit(argv[0]);		/* reads grass env, stores program name to G_program_name() */

    /* initialize module */
    module = G_define_module();
    module->keywords = _("vector, network, centrality measures");
    module->description =
	_("Computes degree, centrality, betweeness, closeness and eigenvector "
	 "centrality measures in the network.");

    /* Define the different options as defined in gis.h */
    map_in = G_define_standard_option(G_OPT_V_INPUT);
    field_opt = G_define_standard_option(G_OPT_V_FIELD);

    map_out = G_define_standard_option(G_OPT_V_OUTPUT);

    cat_opt = G_define_standard_option(G_OPT_V_CATS);
    cat_opt->guisection = _("Selection");
    where_opt = G_define_standard_option(G_OPT_WHERE);
    where_opt->guisection = _("Selection");

    afcol = G_define_standard_option(G_OPT_COLUMN);
    afcol->key = "afcolumn";
    afcol->required = NO;
    afcol->description =
	_("Name of arc forward/both direction(s) cost column");
    afcol->guisection = _("Cost");

    abcol = G_define_standard_option(G_OPT_COLUMN);
    abcol->key = "abcolumn";
    abcol->required = NO;
    abcol->description = _("Name of arc backward direction cost column");
    abcol->guisection = _("Cost");

    deg_opt = G_define_standard_option(G_OPT_COLUMN);
    deg_opt->key = "degree";
    deg_opt->required = NO;
    deg_opt->description = _("Name of degree centrality column");
    deg_opt->guisection = _("Columns");

    close_opt = G_define_standard_option(G_OPT_COLUMN);
    close_opt->key = "closeness";
    close_opt->required = NO;
    close_opt->description = _("Name of closeness centrality column");
    close_opt->guisection = _("Columns");

    betw_opt = G_define_standard_option(G_OPT_COLUMN);
    betw_opt->key = "betweenness";
    betw_opt->required = NO;
    betw_opt->description = _("Name of betweenness centrality column");
    betw_opt->guisection = _("Columns");

    eigen_opt = G_define_standard_option(G_OPT_COLUMN);
    eigen_opt->key = "eigenvector";
    eigen_opt->required = NO;
    eigen_opt->description = _("Name of eigenvector centrality column");
    eigen_opt->guisection = _("Columns");

    iter_opt = G_define_option();
    iter_opt->key = "iterations";
    iter_opt->answer = "1000";
    iter_opt->type = TYPE_INTEGER;
    iter_opt->required = NO;
    iter_opt->description =
	_("Maximum number of iterations to compute eigenvector centrality");

    error_opt = G_define_option();
    error_opt->key = "error";
    error_opt->answer = "0.1";
    error_opt->type = TYPE_DOUBLE;
    error_opt->required = NO;
    error_opt->description =
	_("Cummulative error tolerance for eigenvector centrality");

    geo_f = G_define_flag();
    geo_f->key = 'g';
    geo_f->description =
	_("Use geodesic calculation for longitude-latitude locations");

    add_f = G_define_flag();
    add_f->key = 'a';
    add_f->description = _("Add points on nodes");

    /* options and flags parser */
    if (G_parser(argc, argv))
	exit(EXIT_FAILURE);
    /* TODO: make an option for this */
    mask_type = GV_LINE | GV_BOUNDARY;

    Points = Vect_new_line_struct();
    Cats = Vect_new_cats_struct();

    Vect_check_input_output_name(map_in->answer, map_out->answer,
				 GV_FATAL_EXIT);

    Vect_set_open_level(2);

    if (1 > Vect_open_old(&In, map_in->answer, ""))
	G_fatal_error(_("Unable to open vector map <%s>"), map_in->answer);

    with_z = Vect_is_3d(&In);

    if (0 > Vect_open_new(&Out, map_out->answer, with_z)) {
	Vect_close(&In);
	G_fatal_error(_("Unable to create vector map <%s>"), map_out->answer);
    }


    if (geo_f->answer) {
	geo = 1;
	if (G_projection() != PROJECTION_LL)
	    G_warning(_("The current projection is not longitude-latitude"));
    }
    else
	geo = 0;

    /* parse filter option and select appropriate lines */
    layer = atoi(field_opt->answer);
    chcat =
	(NetA_initialise_varray
	 (&In, layer, mask_type, where_opt->answer, cat_opt->answer,
	  &varray) == 1);

    /* Create table */
    Fi = Vect_default_field_info(&Out, 1, NULL, GV_1TABLE);
    Vect_map_add_dblink(&Out, 1, NULL, Fi->table, "cat", Fi->database,
			Fi->driver);
    db_init_string(&sql);
    driver = db_start_driver_open_database(Fi->driver, Fi->database);
    if (driver == NULL)
	G_fatal_error(_("Unable to open database <%s> by driver <%s>"),
		      Fi->database, Fi->driver);

    db_init_string(&tmp);
    if (deg_opt->answer)
	append_string(&tmp, deg_opt->answer);
    if (close_opt->answer)
	append_string(&tmp, close_opt->answer);
    if (betw_opt->answer)
	append_string(&tmp, betw_opt->answer);
    if (eigen_opt->answer)
	append_string(&tmp, eigen_opt->answer);
    sprintf(buf,
	    "create table %s(cat integer%s)", Fi->table, db_get_string(&tmp));

    db_set_string(&sql, buf);
    G_debug(2, db_get_string(&sql));

    if (db_execute_immediate(driver, &sql) != DB_OK) {
	db_close_database_shutdown_driver(driver);
	G_fatal_error(_("Unable to create table: '%s'"), db_get_string(&sql));
    }

    if (db_create_index2(driver, Fi->table, "cat") != DB_OK)
	G_warning(_("Cannot create index"));

    if (db_grant_on_table
	(driver, Fi->table, DB_PRIV_SELECT, DB_GROUP | DB_PUBLIC) != DB_OK)
	G_fatal_error(_("Cannot grant privileges on table <%s>"), Fi->table);

    db_begin_transaction(driver);

    Vect_copy_head_data(&In, &Out);
    Vect_hist_copy(&In, &Out);
    Vect_hist_command(&Out);

    Vect_net_build_graph(&In, mask_type, atoi(field_opt->answer), 0,
			 afcol->answer, abcol->answer, NULL, geo, 0);
    graph = &(In.graph);
    nnodes = dglGet_NodeCount(graph);

    deg = closeness = betw = eigen = NULL;

    covered = (char *)G_calloc(nnodes + 1, sizeof(char));
    if (!covered)
	G_fatal_error(_("Out of memory"));

    if (deg_opt->answer) {
	deg = (double *)G_calloc(nnodes + 1, sizeof(double));
	if (!deg)
	    G_fatal_error(_("Out of memory"));
    }

    if (close_opt->answer) {
	closeness = (double *)G_calloc(nnodes + 1, sizeof(double));
	if (!closeness)
	    G_fatal_error(_("Out of memory"));
    }

    if (betw_opt->answer) {
	betw = (double *)G_calloc(nnodes + 1, sizeof(double));
	if (!betw)
	    G_fatal_error(_("Out of memory"));
    }

    if (eigen_opt->answer) {
	eigen = (double *)G_calloc(nnodes + 1, sizeof(double));
	if (!eigen)
	    G_fatal_error(_("Out of memory"));
    }


    if (deg_opt->answer) {
	G_message(_("Computing degree centrality measure"));
	NetA_degree_centrality(graph, deg);
    }
    if (betw_opt->answer || close_opt->answer) {
	G_message(_("Computing betweenness and/or closeness centrality measure"));
	NetA_betweenness_closeness(graph, betw, closeness);
	if (closeness)
	    for (i = 1; i <= nnodes; i++)
		closeness[i] /= (double)In.cost_multip;
    }
    if (eigen_opt->answer) {
	G_message(_("Computing eigenvector centrality measure"));
	NetA_eigenvector_centrality(graph, atoi(iter_opt->answer),
				    atof(error_opt->answer), eigen);
    }


    nlines = Vect_get_num_lines(&In);
    G_message(_("Writing data into the table..."));
    G_percent_reset();
    for (i = 1; i <= nlines; i++) {
	G_percent(i, nlines, 1);
	int type = Vect_read_line(&In, Points, Cats, i);

	if (type == GV_POINT && (!chcat || varray->c[i])) {
	    int cat, node;

	    if (!Vect_cat_get(Cats, layer, &cat))
		continue;
	    Vect_reset_cats(Cats);
	    Vect_cat_set(Cats, 1, cat);
	    Vect_write_line(&Out, type, Points, Cats);
	    Vect_get_line_nodes(&In, i, &node, NULL);
	    process_node(node, cat);
	    covered[node] = 1;
	}
    }

    if (add_f->answer && !chcat) {
	max_cat = 0;
	for (i = 1; i <= nlines; i++) {
	    Vect_read_line(&In, NULL, Cats, i);
	    for (j = 0; j < Cats->n_cats; j++)
		if (Cats->cat[j] > max_cat)
		    max_cat = Cats->cat[j];
	}
	max_cat++;
	for (i = 1; i <= nnodes; i++)
	    if (!covered[i]) {
		Vect_reset_cats(Cats);
		Vect_cat_set(Cats, 1, max_cat);
		NetA_add_point_on_node(&In, &Out, i, Cats);
		process_node(i, max_cat);
		max_cat++;
	    }

    }

    db_commit_transaction(driver);
    db_close_database_shutdown_driver(driver);

    G_free(covered);
    if (deg)
	G_free(deg);
    if (closeness)
	G_free(closeness);
    if (betw)
	G_free(betw);
    if (eigen)
	G_free(eigen);
    Vect_build(&Out);

    Vect_close(&In);
    Vect_close(&Out);

    exit(EXIT_SUCCESS);
}