Ejemplo n.º 1
0
Archivo: field.c Proyecto: caomw/grass
/*!
  \brief Get information about link to database (by layer number or layer name)
  
  Note: if <em>field</em> is -1 then the function returns the first
  dblink or NULL
  
  \param Map pointer to Map_info structure
  \param field layer number or name
  
  \return pointer to new field_info structure
  \return NULL if not found
*/
struct field_info *Vect_get_field2(const struct Map_info *Map, const char *field)
{
    int ifield;
    struct field_info *fi;

    G_debug(1, "Vect_get_field2(): field = %s", field);

    fi = NULL;
    ifield = atoi(field);
    
    if (ifield > 0) {
	fi = Vect_get_field(Map, ifield);
	if (fi)
	    return fi;
    }
    else if (ifield == -1) {
      if (Vect_get_num_dblinks(Map) > 0)
	  return Vect_get_dblink(Map, 0); /* return first */
      else
	  return NULL;
    }
    else if (ifield == 0)
	return Vect_get_field_by_name(Map, field);

    return NULL;
}
Ejemplo n.º 2
0
void print_shell(const struct Map_info *Map)
{
    if (Vect_maptype(Map) & (GV_FORMAT_OGR | GV_FORMAT_OGR_DIRECT)) {
	fprintf(stdout, "ogr_layer=%s\n",
		Vect_get_ogr_layer_name(Map));
	fprintf(stdout, "ogr_dsn=%s\n",
		Vect_get_ogr_dsn_name(Map));
    }
    else {
	fprintf(stdout, "name=%s\n",
		Vect_get_name(Map));
	fprintf(stdout, "mapset=%s\n",
		Vect_get_mapset(Map));
    }
    
    fprintf(stdout, "location=%s\n",
	    G_location());
    fprintf(stdout, "database=%s\n",
	    G_gisdbase());
    fprintf(stdout, "title=%s\n",
	    Vect_get_map_name(Map));
    fprintf(stdout, "scale=1:%d\n",
	    Vect_get_scale(Map));
    
    if (Vect_maptype(Map) & (GV_FORMAT_OGR | GV_FORMAT_OGR_DIRECT)) {	
	fprintf(stdout, "format=%s,%s\n",
		Vect_maptype_info(Map), Vect_get_ogr_format_info(Map));
    }
    else {
	fprintf(stdout, "format=%s\n",
		Vect_maptype_info(Map));
    }

    fprintf(stdout, "creator=%s\n",
	    Vect_get_person(Map));
    fprintf(stdout, "organization=%s\n",
	    Vect_get_organization(Map));
    fprintf(stdout, "source_date=%s\n",
	    Vect_get_map_date(Map));
    fprintf(stdout, "level=%d\n", 
	    Vect_level(Map));
    
    if (Vect_level(Map) > 0) {
	fprintf(stdout, "num_dblinks=%d\n",
		Vect_get_num_dblinks(Map));
    }

    fprintf(stdout, "projection=%s\n",
	    Vect_get_proj_name(Map));
    if (G_projection() == PROJECTION_UTM) {
	fprintf(stdout, "zone=%d\n",
		Vect_get_zone(Map));
    }
    fprintf(stdout, "digitization_threshold=%f\n",
	    Vect_get_thresh(Map));
    fprintf(stdout, "comment=%s\n",
	    Vect_get_comment(Map));
}
Ejemplo n.º 3
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));
}
Ejemplo n.º 4
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);
}
Ejemplo n.º 5
0
Archivo: field.c Proyecto: caomw/grass
/*!
  \brief Get field number of given field

  \param Map pointer to Map_info structure
  \param field layer name

  \return layer number
  \return -1 for all layers
  \return 0 if layer not found
*/
int Vect_get_field_number(const struct Map_info *Map, const char *field)
{
    struct field_info *fi;

    G_debug(1, "Vect_get_field_number(): field = %s", field);

    if (strcmp(field, "-1") == 0)
	return -1;

    if (Vect_get_num_dblinks(Map) == 0)
	return atoi(field);
    
    fi = Vect_get_field2(Map, field);

    if (fi)
	return fi->number;

    return atoi(field);
}
Ejemplo n.º 6
0
Archivo: field.c Proyecto: caomw/grass
/*!
  \brief Copy DB links from input vector map to output vector map

  \param In pointer to Map_info structure (input)
  \param Out pointer to Map_info structure (output)
  \param first_only TRUE to copy only first link otherwise all DB links are copied
*/
void Vect_copy_map_dblinks(const struct Map_info *In, struct Map_info *Out,
			   int first_only)
{
    int i, ndblinks;
    struct field_info *Fi;
    
    ndblinks = Vect_get_num_dblinks(In);
    for (i = 0; i < ndblinks; i++) {
	Fi = Vect_get_dblink(In, 0);
	if (!Fi) {
	    G_warning(_("Database connection not defined. Skipping."));
	    continue;
	}
	Vect_map_add_dblink(Out, Fi->number, Fi->name, Fi->table, Fi->key,
			    Fi->database, Fi->driver);
	
	if (first_only && ndblinks > 1)
	    G_warning(_("More DB links defined for input vector map. "
			"Using only first DB link for output."));
    }
}
Ejemplo n.º 7
0
void print_info(const struct Map_info *Map)
{
    int i, map_type;
    char line[1024];
    char timebuff[256];
    struct TimeStamp ts;
    int time_ok, first_time_ok, second_time_ok;
    struct bound_box box;
    char tmp1[1024], tmp2[1024];
    
    time_ok = first_time_ok = second_time_ok = FALSE;
    map_type = Vect_maptype(Map);
    
    /* Check the Timestamp */
    time_ok = G_read_vector_timestamp(Vect_get_name(Map), NULL, "", &ts);

    /* Check for valid entries, show none if no timestamp available */
    if (time_ok == TRUE) {
        if (ts.count > 0)
            first_time_ok = TRUE;
        if (ts.count > 1)
            second_time_ok = TRUE;
    }

    divider('+');
    sprintf(line, "%-17s%s", _("Name:"),
            Vect_get_name(Map));
    printline(line);
    sprintf(line, "%-17s%s", _("Mapset:"),
            Vect_get_mapset(Map));
    printline(line);
    
    sprintf(line, "%-17s%s", _("Location:"),
            G_location());
    printline(line);
    sprintf(line, "%-17s%s", _("Database:"),
            G_gisdbase());
    printline(line);

    sprintf(line, "%-17s%s", _("Title:"),
            Vect_get_map_name(Map));
    printline(line);
    sprintf(line, "%-17s1:%d", _("Map scale:"),
            Vect_get_scale(Map));
    printline(line);

    sprintf(line, "%-17s%s", _("Name of creator:"),
            Vect_get_person(Map));
    printline(line);
    sprintf(line, "%-17s%s", _("Organization:"),
            Vect_get_organization(Map));
    printline(line);
    sprintf(line, "%-17s%s", _("Source date:"),
            Vect_get_map_date(Map));
    printline(line);

    /* This shows the TimeStamp (if present) */
    if (time_ok  == TRUE && (first_time_ok || second_time_ok)) {
        G_format_timestamp(&ts, timebuff);
        sprintf(line, "%-17s%s", _("Timestamp (first layer): "), timebuff);
        printline(line);
    }
    else {
        strcpy(line, _("Timestamp (first layer): none"));
        printline(line);
    }
    
    divider('|');
    
    if (map_type == GV_FORMAT_OGR ||
        map_type == GV_FORMAT_OGR_DIRECT) {
        sprintf(line, "%-17s%s (%s)", _("Map format:"),
                Vect_maptype_info(Map), Vect_get_finfo_format_info(Map));
        printline(line);
        
        /* for OGR format print also datasource and layer */
        sprintf(line, "%-17s%s", _("OGR layer:"),
                Vect_get_finfo_layer_name(Map));
        printline(line);
        sprintf(line, "%-17s%s", _("OGR datasource:"),
                Vect_get_finfo_dsn_name(Map));
        printline(line);
        sprintf(line, "%-17s%s", _("Feature type:"),
                Vect_get_finfo_geometry_type(Map));
        printline(line);
    }
    else if (map_type == GV_FORMAT_POSTGIS) {
        int topo_format;
        char *toposchema_name, *topogeom_column;
        int topo_geo_only;

        const struct Format_info *finfo;

        finfo = Vect_get_finfo(Map);
        
        sprintf(line, "%-17s%s (%s)", _("Map format:"),
                Vect_maptype_info(Map), Vect_get_finfo_format_info(Map));
        printline(line);
        
        /* for PostGIS format print also datasource and layer */
        sprintf(line, "%-17s%s", _("DB table:"),
                Vect_get_finfo_layer_name(Map));
        printline(line);
        sprintf(line, "%-17s%s", _("DB name:"),
                Vect_get_finfo_dsn_name(Map));
        printline(line);

        sprintf(line, "%-17s%s", _("Geometry column:"),
                finfo->pg.geom_column);
        printline(line);

        sprintf(line, "%-17s%s", _("Feature type:"),
                Vect_get_finfo_geometry_type(Map));
        printline(line);


        
        topo_format = Vect_get_finfo_topology_info(Map,
                                                   &toposchema_name, &topogeom_column,
                                                   &topo_geo_only);
        if (topo_format == GV_TOPO_POSTGIS) {
            sprintf(line, "%-17s%s (%s %s%s)", _("Topology:"), "PostGIS",
                    _("schema:"), toposchema_name,
                    topo_geo_only ? ", topo-geo-only: yes" : "");
            printline(line);

            sprintf(line, "%-17s%s", _("Topology column:"),
                    topogeom_column);
        }
        else
            sprintf(line, "%-17s%s", _("Topology:"), "pseudo (simple features)");
        
        printline(line);
    }
    else {
        sprintf(line, "%-17s%s", _("Map format:"),
                Vect_maptype_info(Map));
        printline(line);
    }
    

    divider('|');
    
    sprintf(line, "  %s: %s (%s: %i)",
            _("Type of map"), _("vector"), _("level"), Vect_level(Map));
    printline(line);
    
    if (Vect_level(Map) > 0) {
        printline("");
        sprintf(line,
                "  %-24s%-9d       %-22s%-9d",
                _("Number of points:"), 
                Vect_get_num_primitives(Map, GV_POINT),
                _("Number of centroids:"),
                Vect_get_num_primitives(Map, GV_CENTROID));
        printline(line);
        sprintf(line,
                "  %-24s%-9d       %-22s%-9d",
                _("Number of lines:"),
                Vect_get_num_primitives(Map, GV_LINE),
                _("Number of boundaries:"),
                Vect_get_num_primitives(Map, GV_BOUNDARY));
        printline(line);
        sprintf(line,
                "  %-24s%-9d       %-22s%-9d",
                _("Number of areas:"),
                Vect_get_num_areas(Map),
                _("Number of islands:"),
                Vect_get_num_islands(Map));
        printline(line);
        if (Vect_is_3d(Map)) {
            sprintf(line,
                    "  %-24s%-9d       %-22s%-9d",
                    _("Number of faces:"),
                    Vect_get_num_primitives(Map, GV_FACE),
                    _("Number of kernels:"),
                    Vect_get_num_primitives(Map, GV_KERNEL));
            printline(line);
            sprintf(line,
                    "  %-24s%-9d       %-22s%-9d",
                    _("Number of volumes:"),
                    Vect_get_num_volumes(Map),
                    _("Number of holes:"),
                    Vect_get_num_holes(Map));
            printline(line);
        }
        printline("");

        sprintf(line, "  %-24s%s",
                _("Map is 3D:"),
                Vect_is_3d(Map) ? _("Yes") : _("No"));
        printline(line);
        sprintf(line, "  %-24s%-9d",
                _("Number of dblinks:"),
                Vect_get_num_dblinks(Map));
        printline(line);
    }

    printline("");
    /* this differs from r.info in that proj info IS taken from the map here, not the location settings */
    /* Vect_get_proj_name() and _zone() are typically unset?! */
    if (G_projection() == PROJECTION_UTM) {
        int utm_zone;

        utm_zone = Vect_get_zone(Map);
        if (utm_zone < 0 || utm_zone > 60)
            strcpy(tmp1, _("invalid"));
        else if (utm_zone == 0)
            strcpy(tmp1, _("unspecified"));
        else
            sprintf(tmp1, "%d", utm_zone);

        sprintf(line, "  %s: %s (%s %s)",
                _("Projection"), Vect_get_proj_name(Map),
                _("zone"), tmp1);
    }
    else
        sprintf(line, "  %s: %s",
                _("Projection"), Vect_get_proj_name(Map));

    printline(line);
    printline("");

    Vect_get_map_box(Map, &box);

    G_format_northing(box.N, tmp1, G_projection());
    G_format_northing(box.S, tmp2, G_projection());
    sprintf(line, "              %c: %17s    %c: %17s",
            'N', tmp1, 'S', tmp2);
    printline(line);
    
    G_format_easting(box.E, tmp1, G_projection());
    G_format_easting(box.W, tmp2, G_projection());
    sprintf(line, "              %c: %17s    %c: %17s",
            'E', tmp1, 'W', tmp2);
    printline(line);
    
    if (Vect_is_3d(Map)) {
        format_double(box.B, tmp1);
        format_double(box.T, tmp2);
        sprintf(line, "              %c: %17s    %c: %17s",
                'B', tmp1, 'T', tmp2);
        printline(line);
    }
    printline("");

    format_double(Vect_get_thresh(Map), tmp1);
    sprintf(line, "  %s: %s", _("Digitization threshold"), tmp1);
    printline(line);
    sprintf(line, "  %s:", _("Comment"));
    printline(line);
    sprintf(line, "    %s", Vect_get_comment(Map));
    printline(line);
    divider('+');
    fprintf(stdout, "\n");
}
Ejemplo n.º 8
0
void print_shell(const struct Map_info *Map, const char *field_opt)
{
    int map_type;
    int time_ok, first_time_ok, second_time_ok;
    char timebuff[256];
    struct field_info *fi;
    struct TimeStamp ts;
        
    time_ok = first_time_ok = second_time_ok = FALSE;
    
    /* Check the Timestamp */
    time_ok = G_read_vector_timestamp(Vect_get_name(Map), NULL, "", &ts);
    
    /* Check for valid entries, show none if no timestamp available */
    if (time_ok == TRUE) {
        if (ts.count > 0)
            first_time_ok = TRUE;
        if (ts.count > 1)
            second_time_ok = TRUE;
    }

    map_type = Vect_maptype(Map);
    
    fprintf(stdout, "name=%s\n",
            Vect_get_name(Map));
    fprintf(stdout, "mapset=%s\n",
            Vect_get_mapset(Map));
    fprintf(stdout, "location=%s\n",
            G_location());
    fprintf(stdout, "database=%s\n",
            G_gisdbase());
    fprintf(stdout, "title=%s\n",
            Vect_get_map_name(Map));
    fprintf(stdout, "scale=1:%d\n",
            Vect_get_scale(Map));
    fprintf(stdout, "creator=%s\n",
            Vect_get_person(Map));
    fprintf(stdout, "organization=%s\n",
            Vect_get_organization(Map));
    fprintf(stdout, "source_date=%s\n",
            Vect_get_map_date(Map));
    /* This shows the TimeStamp (if present) */
    if (time_ok  == TRUE && (first_time_ok || second_time_ok)) {
        G_format_timestamp(&ts, timebuff);
        fprintf(stdout, "timestamp=%s\n", timebuff);
    }
    else {
        fprintf(stdout, "timestamp=none\n");
    }

    if (map_type == GV_FORMAT_OGR ||
        map_type == GV_FORMAT_OGR_DIRECT) {
        fprintf(stdout, "format=%s,%s\n",
                Vect_maptype_info(Map), Vect_get_finfo_format_info(Map));
        fprintf(stdout, "ogr_layer=%s\n",
                Vect_get_finfo_layer_name(Map));
        fprintf(stdout, "ogr_dsn=%s\n",
                Vect_get_finfo_dsn_name(Map));
        fprintf(stdout, "feature_type=%s\n",
                Vect_get_finfo_geometry_type(Map));

    }
    else if (map_type == GV_FORMAT_POSTGIS) {
        int topo_format;
        char *toposchema_name, *topogeom_column;
        const struct Format_info *finfo;

        finfo = Vect_get_finfo(Map);
        
        fprintf(stdout, "format=%s,%s\n",
                Vect_maptype_info(Map), Vect_get_finfo_format_info(Map));
        fprintf(stdout, "pg_table=%s\n",
                Vect_get_finfo_layer_name(Map));
        fprintf(stdout, "pg_dbname=%s\n",
                Vect_get_finfo_dsn_name(Map));
        fprintf(stdout, "geometry_column=%s\n",
                finfo->pg.geom_column);
        fprintf(stdout, "feature_type=%s\n",
                Vect_get_finfo_geometry_type(Map));
        topo_format = Vect_get_finfo_topology_info(Map, &toposchema_name, &topogeom_column, NULL);
        if (topo_format == GV_TOPO_POSTGIS) {
            fprintf(stdout, "pg_topo_schema=%s\n",
                    toposchema_name);
            fprintf(stdout, "pg_topo_column=%s\n",
                    topogeom_column);
        }
    }
    else {
        fprintf(stdout, "format=%s\n",
                Vect_maptype_info(Map));
    }

    fprintf(stdout, "level=%d\n", 
            Vect_level(Map));
    
    if (Vect_level(Map) > 0) {
        fprintf(stdout, "num_dblinks=%d\n",
                Vect_get_num_dblinks(Map));

        if (Vect_get_num_dblinks(Map) > 0) {
            fi = Vect_get_field2(Map, field_opt);
            if(fi != NULL) {
                fprintf(stdout, "attribute_layer_number=%i\n",fi->number);
                fprintf(stdout, "attribute_layer_name=%s\n",fi->name);
                fprintf(stdout, "attribute_database=%s\n",fi->database);
                fprintf(stdout, "attribute_database_driver=%s\n",fi->driver);
                fprintf(stdout, "attribute_table=%s\n",fi->table);
                fprintf(stdout, "attribute_primary_key=%s\n",fi->key);
            }
        }
    }

    fprintf(stdout, "projection=%s\n",
            Vect_get_proj_name(Map));
    if (G_projection() == PROJECTION_UTM) {
        fprintf(stdout, "zone=%d\n",
                Vect_get_zone(Map));
    }
    fprintf(stdout, "digitization_threshold=%f\n",
            Vect_get_thresh(Map));
    fprintf(stdout, "comment=%s\n",
            Vect_get_comment(Map));
}
Ejemplo n.º 9
0
/*!
   \brief Copy tables linked to vector map.

   All if field = 0, or table defined by given field if field > 0
   Notice, that if input map has no tables defined, it will copy
   nothing and return 0 (success).

   \param In input vector map
   \param[out] Out output vector map
   \param field layer number

   \return 0 on success
   \return -1 on error
 */
int Vect_copy_tables(const struct Map_info *In, struct Map_info *Out,
		     int field)
{
    int i, n, ret, type;
    struct field_info *Fi, *Fin;
    dbDriver *driver;

    n = Vect_get_num_dblinks(In);

    G_debug(2, "Vect_copy_tables(): copying %d tables", n);

    type = GV_1TABLE;
    if (n > 1)
	type = GV_MTABLE;

    for (i = 0; i < n; i++) {
	Fi = Vect_get_dblink(In, i);
	if (Fi == NULL) {
	    G_warning(_("Database connection not defined for layer %d"),
		      In->dblnk->field[i].number);
	    return -1;
	}
	if (field > 0 && Fi->number != field)
	    continue;

	Fin = Vect_default_field_info(Out, Fi->number, Fi->name, type);
	G_debug(2, "Copy drv:db:table '%s:%s:%s' to '%s:%s:%s'",
		Fi->driver, Fi->database, Fi->table, Fin->driver,
		Fin->database, Fin->table);

	ret =
	    Vect_map_add_dblink(Out, Fi->number, Fi->name, Fin->table,
				Fi->key, Fin->database, Fin->driver);
	if (ret == -1) {
	    G_warning(_("Unable to add database link for vector map <%s>"),
		      Out->name);
	    return -1;
	}

	ret = db_copy_table(Fi->driver, Fi->database, Fi->table,
			    Fin->driver, Vect_subst_var(Fin->database, Out),
			    Fin->table);
	if (ret == DB_FAILED) {
	    G_warning(_("Unable to copy table <%s>"), Fin->table);
	    return -1;
	}

	driver =
	    db_start_driver_open_database(Fin->driver,
					  Vect_subst_var(Fin->database, Out));
	if (driver == NULL) {
	    G_warning(_("Unable to open database <%s> by driver <%s>"),
		      Fin->database, Fin->driver);
	}
	else {
	    if (db_create_index2(driver, Fin->table, Fi->key) != DB_OK)
		G_warning(_("Unable to create index for table <%s>, key <%s>"),
			  Fin->table, Fin->key);

	    db_close_database_shutdown_driver(driver);
	}
    }

    return 0;
}
Ejemplo n.º 10
0
/*!
   \brief Delete vector map including attribute tables

   \param map vector map name

   \return -1 error
   \return 0 success
 */
int Vect_delete(const char *map)
{
    int i, n, ret;
    struct Map_info Map;
    struct field_info *Fi;
    char buf[GPATH_MAX];
    DIR *dir;
    struct dirent *ent;
    const char *tmp;
    char xname[GNAME_MAX], xmapset[GMAPSET_MAX];

    G_debug(3, "Delete vector '%s'", map);

    /* remove mapset from fully qualified name */
    if (G_name_is_fully_qualified(map, xname, xmapset)) {
	map = xname;
    }

    if (map == NULL || strlen(map) == 0) {
	G_warning(_("Invalid vector map name <%s>"), map ? map : "null");
	return -1;
    }

    sprintf(buf, "%s/%s/%s/%s/%s/%s", G_gisdbase(), G_location(),
	    G_mapset(), GV_DIRECTORY, map, GV_DBLN_ELEMENT);

    G_debug(1, "dbln file: %s", buf);

    if (access(buf, F_OK) == 0) {
	/* Open input */
	Vect_set_open_level(1);	/* Topo not needed */
	ret = Vect_open_old_head(&Map, map, G_mapset());
	if (ret < 1) {
	    G_warning(_("Unable to open header file for vector map <%s>"),
		      map);
	    return -1;
	}

	/* Delete all tables, NOT external (OGR) */
	if (Map.format == GV_FORMAT_NATIVE) {

	    n = Vect_get_num_dblinks(&Map);
	    for (i = 0; i < n; i++) {
		Fi = Vect_get_dblink(&Map, i);
		if (Fi == NULL) {
		    G_warning(_("Database connection not defined for layer %d"),
			      Map.dblnk->field[i].number);
		    Vect_close(&Map);
		    return -1;
		}
		G_debug(3, "Delete drv:db:table '%s:%s:%s'", Fi->driver,
			Fi->database, Fi->table);

		ret = db_table_exists(Fi->driver, Fi->database, Fi->table);
		if (ret == -1) {
		    G_warning(_("Unable to find table <%s> linked to vector map <%s>"),
			      Fi->table, map);
		    Vect_close(&Map);
		    return -1;
		}

		if (ret == 1) {
		    ret =
			db_delete_table(Fi->driver, Fi->database, Fi->table);
		    if (ret == DB_FAILED) {
			G_warning(_("Unable to delete table <%s>"),
				  Fi->table);
			Vect_close(&Map);
			return -1;
		    }
		}
		else {
		    G_warning(_("Table <%s> linked to vector map <%s> does not exist"),
			      Fi->table, map);
		}
	    }
	}
	Vect_close(&Map);
    }

    /* Delete all files from vector/name directory */
    sprintf(buf, "%s/%s/vector/%s", G_location_path(), G_mapset(), map);
    G_debug(3, "opendir '%s'", buf);
    dir = opendir(buf);
    if (dir == NULL) {
	G_warning(_("Unable to open directory '%s'"), buf);
	return -1;
    }

    while ((ent = readdir(dir))) {
	G_debug(3, "file = '%s'", ent->d_name);
	if ((strcmp(ent->d_name, ".") == 0) ||
	    (strcmp(ent->d_name, "..") == 0))
	    continue;
	sprintf(buf, "%s/%s/vector/%s/%s", G_location_path(), G_mapset(), map,
		ent->d_name);
	G_debug(3, "delete file '%s'", buf);
	ret = unlink(buf);
	if (ret == -1) {
	    G_warning(_("Unable to delete file '%s'"), buf);
	    closedir(dir);
	    return -1;
	}
    }
    closedir(dir);

    /* NFS can create .nfsxxxxxxxx files for those deleted 
     *  -> we have to move the directory to ./tmp before it is deleted */
    sprintf(buf, "%s/%s/vector/%s", G_location_path(), G_mapset(), map);

    tmp = G_tempfile();

    G_debug(3, "rename '%s' to '%s'", buf, tmp);
    ret = rename(buf, tmp);

    if (ret == -1) {
	G_warning(_("Unable to rename directory '%s' to '%s'"), buf, tmp);
	return -1;
    }

    G_debug(3, "remove directory '%s'", tmp);
    /* Warning: remove() fails on Windows */
    ret = rmdir(tmp);
    if (ret == -1) {
	G_warning(_("Unable to remove directory '%s'"), tmp);
	return -1;
    }

    return 0;
}
Ejemplo n.º 11
0
int main(int argc, char *argv[])
{
    int i, iopt;
    int operator;
    int aline, nalines, nskipped;
    int ltype, itype[2], ifield[2];
    int **cats, *ncats, nfields, *fields;
    char *mapset[2], *pre[2];
    struct GModule *module;
    struct GParm parm;
    struct GFlag flag;
    struct Map_info In[2], Out;
    struct field_info *IFi, *OFi;
    struct line_pnts *APoints, *BPoints;
    struct line_cats *ACats, *BCats;
    int *ALines;		/* List of lines: 0 do not output, 1 - write to output */
    struct ilist *List, *TmpList, *BoundList;

    G_gisinit(argv[0]);

    pre[0] = "a";
    pre[1] = "b";

    module = G_define_module();
    module->keywords = _("vector, spatial query");
    module->description =
	_("Selects features from vector map (A) by features from other vector map (B).");

    parse_options(&parm, &flag);
    
    if (G_parser(argc, argv))
	exit(EXIT_FAILURE);
    
    if (parm.operator->answer[0] == 'e')
	operator = OP_EQUALS;
    else if (parm.operator->answer[0] == 'd') {
	/* operator = OP_DISJOINT; */
	operator = OP_INTERSECTS;
	flag.reverse->answer = YES;
    }
    else if (parm.operator->answer[0] == 'i')
	operator = OP_INTERSECTS;
    else if (parm.operator->answer[0] == 't')
	operator = OP_TOUCHES;
    else if (parm.operator->answer[0] == 'c' && parm.operator->answer[1] == 'r')
	operator = OP_CROSSES;
    else if (parm.operator->answer[0] == 'w')
	operator = OP_WITHIN;
    else if (parm.operator->answer[0] == 'c' && parm.operator->answer[1] == 'o')
	operator = OP_CONTAINS;
    else if (parm.operator->answer[0] == 'o') {
	if (strcmp(parm.operator->answer, "overlaps") == 0)
	    operator = OP_OVERLAPS;
	else
	    operator = OP_OVERLAP;
    }
    else if (parm.operator->answer[0] == 'r')
	operator = OP_RELATE;
    else
	G_fatal_error(_("Unknown operator"));
    
    if (operator == OP_RELATE && !parm.relate->answer) {
	G_fatal_error(_("Required parameter <%s> not set"),
		      parm.relate->key);
    }
    
    for (iopt = 0; iopt < 2; iopt++) {
	itype[iopt] = Vect_option_to_types(parm.type[iopt]);
	ifield[iopt] = atoi(parm.field[iopt]->answer);

	Vect_check_input_output_name(parm.input[iopt]->answer, parm.output->answer,
				     GV_FATAL_EXIT);

	if ((mapset[iopt] =
	     G_find_vector2(parm.input[iopt]->answer, NULL)) == NULL) {
	    G_fatal_error(_("Vector map <%s> not found"),
			  parm.input[iopt]->answer);
	}
	
	Vect_set_open_level(2);
	Vect_open_old(&(In[iopt]), parm.input[iopt]->answer, mapset[iopt]);
    }
    
    /* Read field info */
    IFi = Vect_get_field(&(In[0]), ifield[0]);

    APoints = Vect_new_line_struct();
    BPoints = Vect_new_line_struct();
    ACats = Vect_new_cats_struct();
    BCats = Vect_new_cats_struct();
    List = Vect_new_list();
    TmpList = Vect_new_list();
    BoundList = Vect_new_list();

    /* Open output */
    Vect_open_new(&Out, parm.output->answer, Vect_is_3d(&(In[0])));
    Vect_set_map_name(&Out, _("Output from v.select"));
    Vect_set_person(&Out, G_whoami());
    Vect_copy_head_data(&(In[0]), &Out);
    Vect_hist_copy(&(In[0]), &Out);
    Vect_hist_command(&Out);

    nskipped = 0;
    nalines = Vect_get_num_lines(&(In[0]));

#ifdef HAVE_GEOS
    initGEOS(G_message, G_fatal_error);
    GEOSGeometry *AGeom = NULL;
#else
    void *AGeom = NULL;
#endif

    /* Alloc space for input lines array */
    ALines = (int *)G_calloc(nalines + 1, sizeof(int));

    G_message(_("Building spatial index..."));
    Vect_build_spatial_index(&In[0]);
    Vect_build_spatial_index(&In[1]);
    
    /* Lines in A. Go through all lines and mark those that meets condition */
    if (itype[0] & (GV_POINTS | GV_LINES)) {
	G_message(_("Processing features..."));
	
	for (aline = 1; aline <= nalines; aline++) {
	    BOUND_BOX abox;

	    G_debug(3, "aline = %d", aline);
	    G_percent(aline, nalines, 2);	/* must be before any continue */

	    /* Check category */
	    if (!flag.cat->answer && Vect_get_line_cat(&(In[0]), aline, ifield[0]) < 0) {
		nskipped++;
		continue;
	    }

	    /* Read line and check type */
	    if (operator != OP_OVERLAP) {
#ifdef HAVE_GEOS
		AGeom = Vect_read_line_geos(&(In[0]), aline, &ltype);
#endif
		if (!(ltype & (GV_POINT | GV_LINE)))
		    continue;

		if (!AGeom)
		    G_fatal_error(_("Unable to read line id %d from vector map <%s>"),
				  aline, Vect_get_full_name(&(In[0])));
	    }
	    else {
		ltype = Vect_read_line(&(In[0]), APoints, NULL, aline);
	    }
	    
	    if (!(ltype & itype[0]))
		continue;
	    
	    Vect_get_line_box(&(In[0]), aline, &abox);
	    abox.T = PORT_DOUBLE_MAX;
	    abox.B = -PORT_DOUBLE_MAX;

	    /* Check if this line overlaps any feature in B */
	    /* x Lines in B */
	    if (itype[1] & (GV_POINTS | GV_LINES)) {
		int i;
		int found = 0;
		
		/* Lines */
		Vect_select_lines_by_box(&(In[1]), &abox, itype[1], List);
		for (i = 0; i < List->n_values; i++) {
		    int bline;
		    
		    bline = List->value[i];
		    G_debug(3, "  bline = %d", bline);
		    
		    /* Check category */
		    if (!flag.cat->answer && Vect_get_line_cat(&(In[1]), bline, ifield[1]) < 0) {
			nskipped++;
			continue;
		    }
		    
		    if (operator != OP_OVERLAP) {
#ifdef HAVE_GEOS
			if(line_relate_geos(&(In[1]), AGeom,
					    bline, operator, parm.relate->answer)) {

			    found = 1;
			    break;
			}
#endif
		    }
		    else {
			Vect_read_line(&(In[1]), BPoints, NULL, bline);

			if (Vect_line_check_intersection(APoints, BPoints, 0)) {
			    found = 1;
			    break;
			}
		    }
		}
		
		if (found) {
		    ALines[aline] = 1;
		    continue;	/* Go to next A line */
		}
	    }
	    
	    /* x Areas in B. */
	    if (itype[1] & GV_AREA) {
		int i;
		
		Vect_select_areas_by_box(&(In[1]), &abox, List);
		for (i = 0; i < List->n_values; i++) {
		    int barea;
		    
		    barea = List->value[i];
		    G_debug(3, "  barea = %d", barea);
		    
		    if (Vect_get_area_cat(&(In[1]), barea, ifield[1]) < 0) {
			nskipped++;
			continue;
		    }

		    if (operator != OP_OVERLAP) {
#ifdef HAVE_GEOS
			if(area_relate_geos(&(In[1]), AGeom,
					    barea, operator, parm.relate->answer)) {
			    ALines[aline] = 1;
			    break;
			}
#endif
		    }
		    else {
			if (line_overlap_area(&(In[0]), aline, &(In[1]), barea)) {
			    ALines[aline] = 1;
			    break;
			}
		    }
		}
	    }
	    if (operator != OP_OVERLAP) {
#ifdef HAVE_GEOS
		GEOSGeom_destroy(AGeom);
#endif
		AGeom = NULL;
	    }
	}
    }
    
    /* Areas in A. */
    if (itype[0] & GV_AREA) {
	int aarea, naareas;

	G_message(_("Processing areas..."));
	
	naareas = Vect_get_num_areas(&(In[0]));

	for (aarea = 1; aarea <= naareas; aarea++) {
	    BOUND_BOX abox;

	    G_percent(aarea, naareas, 2);	/* must be before any continue */

	    if (Vect_get_area_cat(&(In[0]), aarea, ifield[0]) < 0) {
		nskipped++;
		continue;
	    }
	
	    Vect_get_area_box(&(In[0]), aarea, &abox);
	    abox.T = PORT_DOUBLE_MAX;
	    abox.B = -PORT_DOUBLE_MAX;

	    if (operator != OP_OVERLAP) {
#ifdef HAVE_GEOS
		AGeom = Vect_read_area_geos(&(In[0]), aarea);
#endif
		if (!AGeom)
		    G_fatal_error(_("Unable to read area id %d from vector map <%s>"),
				  aline, Vect_get_full_name(&(In[0])));
	    }

	    /* x Lines in B */
	    if (itype[1] & (GV_POINTS | GV_LINES)) {
		Vect_select_lines_by_box(&(In[1]), &abox, itype[1], List);

		for (i = 0; i < List->n_values; i++) {
		    int bline;

		    bline = List->value[i];

		    if (!flag.cat->answer && Vect_get_line_cat(&(In[1]), bline, ifield[1]) < 0) {
			nskipped++;
			continue;
		    }
		    
		    if (operator != OP_OVERLAP) {
#ifdef HAVE_GEOS
			if(line_relate_geos(&(In[1]), AGeom,
					    bline, operator, parm.relate->answer)) {
			    add_aarea(&(In[0]), aarea, ALines);
			    break;
			}
#endif
		    }
		    else {
			if (line_overlap_area(&(In[1]), bline, &(In[0]), aarea)) {
			    add_aarea(&(In[0]), aarea, ALines);
			    continue;
			}
		    }
		}
	    }

	    /* x Areas in B */
	    if (itype[1] & GV_AREA) {
		int naisles;
		int found = 0;

		/* List of areas B */

		/* Make a list of features forming area A */
		Vect_reset_list(List);

		Vect_get_area_boundaries(&(In[0]), aarea, BoundList);
		for (i = 0; i < BoundList->n_values; i++) {
		    Vect_list_append(List, abs(BoundList->value[i]));
		}

		naisles = Vect_get_area_num_isles(&(In[0]), aarea);

		for (i = 0; i < naisles; i++) {
		    int j, aisle;

		    aisle = Vect_get_area_isle(&(In[0]), aarea, i);

		    Vect_get_isle_boundaries(&(In[0]), aisle, BoundList);
		    for (j = 0; j < BoundList->n_values; j++) {
			Vect_list_append(List, BoundList->value[j]);
		    }
		}

		Vect_select_areas_by_box(&(In[1]), &abox, TmpList);

		for (i = 0; i < List->n_values; i++) {
		    int j, aline;

		    aline = abs(List->value[i]);

		    for (j = 0; j < TmpList->n_values; j++) {
			int barea, bcentroid;

			barea = TmpList->value[j];
			G_debug(3, "  barea = %d", barea);

			if (Vect_get_area_cat(&(In[1]), barea, ifield[1]) < 0) {
			    nskipped++;
			    continue;
			}

			/* Check if any centroid of area B is in area A.
			 * This test is important in if area B is completely within area A */
			bcentroid = Vect_get_area_centroid(&(In[1]), barea);
			Vect_read_line(&(In[1]), BPoints, NULL, bcentroid);

			if (operator != OP_OVERLAP) {
#ifdef HAVE_GEOS
			    if(area_relate_geos(&(In[1]), AGeom,
						barea, operator, parm.relate->answer)) {
				found = 1;
				break;
			    }
#endif
			}
			else {
			    if (Vect_point_in_area(&(In[0]), aarea,
						   BPoints->x[0], BPoints->y[0])) {
				found = 1;
				break;
			    }
			    
			    /* Check intersectin of lines from List with area B */
			    if (line_overlap_area(&(In[0]), aline,
						  &(In[1]), barea)) {
				found = 1;
				break;
			    }
			}
		    }
		    if (found) {
			add_aarea(&(In[0]), aarea, ALines);
			break;
		    }
		}
	    }
	    if (operator != OP_OVERLAP) {
#ifdef HAVE_GEOS
		GEOSGeom_destroy(AGeom);
#endif
		AGeom = NULL;
	    }
	}
    }
    
    Vect_close(&(In[1]));

#ifdef HAVE_GEOS
    finishGEOS();
#endif

    /* Write lines */
    nfields = Vect_cidx_get_num_fields(&(In[0]));
    cats = (int **)G_malloc(nfields * sizeof(int *));
    ncats = (int *)G_malloc(nfields * sizeof(int));
    fields = (int *)G_malloc(nfields * sizeof(int));
    for (i = 0; i < nfields; i++) {
	ncats[i] = 0;
	cats[i] =
	    (int *)G_malloc(Vect_cidx_get_num_cats_by_index(&(In[0]), i) *
			    sizeof(int));
	fields[i] = Vect_cidx_get_field_number(&(In[0]), i);
    }

    G_message(_("Writing selected features..."));
    for (aline = 1; aline <= nalines; aline++) {
	int atype;

	G_debug(4, "aline = %d ALines[aline] = %d", aline, ALines[aline]);
	G_percent(aline, nalines, 2);
	
	if ((!flag.reverse->answer && !(ALines[aline])) ||
	    (flag.reverse->answer && ALines[aline]))
	    continue;

	atype = Vect_read_line(&(In[0]), APoints, ACats, aline);
	Vect_write_line(&Out, atype, APoints, ACats);

	if (!(flag.table->answer) && (IFi != NULL)) {
	    for (i = 0; i < ACats->n_cats; i++) {
		int f, j;

		for (j = 0; j < nfields; j++) {	/* find field */
		    if (fields[j] == ACats->field[i]) {
			f = j;
			break;
		    }
		}
		cats[f][ncats[f]] = ACats->cat[i];
		ncats[f]++;
	    }
	}
    }

    /* Copy tables */
    if (!(flag.table->answer)) {
	int ttype, ntabs = 0;

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

	/* Number of output tabs */
	for (i = 0; i < Vect_get_num_dblinks(&(In[0])); i++) {
	    int f, j;

	    IFi = Vect_get_dblink(&(In[0]), i);

	    for (j = 0; j < nfields; j++) {	/* find field */
		if (fields[j] == IFi->number) {
		    f = j;
		    break;
		}
	    }
	    if (ncats[f] > 0)
		ntabs++;
	}

	if (ntabs > 1)
	    ttype = GV_MTABLE;
	else
	    ttype = GV_1TABLE;

	for (i = 0; i < nfields; i++) {
	    int ret;

	    if (fields[i] == 0)
		continue;

	    /* Make a list of categories */
	    IFi = Vect_get_field(&(In[0]), fields[i]);
	    if (!IFi) {		/* no table */
		G_warning(_("Layer %d - no table"), fields[i]);
		continue;
	    }

	    OFi =
		Vect_default_field_info(&Out, IFi->number, IFi->name, ttype);

	    ret =
		db_copy_table_by_ints(IFi->driver, IFi->database, IFi->table,
				      OFi->driver,
				      Vect_subst_var(OFi->database, &Out),
				      OFi->table, IFi->key, cats[i],
				      ncats[i]);

	    if (ret == DB_FAILED) {
		G_warning(_("Layer %d - unable to copy table"), fields[i]);
	    }
	    else {
		Vect_map_add_dblink(&Out, OFi->number, OFi->name, OFi->table,
				    IFi->key, OFi->database, OFi->driver);
	    }
	}
    }

    Vect_close(&(In[0]));

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

    if (nskipped > 0) {
      G_warning(_("%d features without category skipped"), nskipped);
    }

    G_done_msg(_("%d features written to output."), Vect_get_num_lines(&Out));

    exit(EXIT_SUCCESS);
}
Ejemplo n.º 12
0
/*!
  \brief Write OGR feature

   \param Map pointer to Map_info structure
   \param type feature type (GV_POINT, GV_LINE, ...)
   \param bpoints feature geometry
   \param cats feature categories
   \param ipoints isle geometry for polygons on NULL
   \param nisles number of isles
   
   \return feature offset into file
   \return -1 on error
*/
off_t write_feature(struct Map_info *Map, int type,
                    const struct line_pnts **p_points, int nparts,
                    const struct line_cats *cats)
{
    int i, cat, ret;

    struct field_info *Fi;
    const struct line_pnts *points;
    struct Format_info_ogr *ogr_info;
    struct Format_info_offset *offset_info;
    
    off_t offset;
    
    OGRGeometryH       Ogr_geometry;
    OGRFeatureH        Ogr_feature;
    OGRFeatureDefnH    Ogr_featuredefn;
    OGRwkbGeometryType Ogr_geom_type;

    ogr_info = &(Map->fInfo.ogr);
    offset_info = &(ogr_info->offset);
    
    if (nparts < 1)
        return -1;
    
    points = p_points[0]; /* feature geometry */
    
    if (!ogr_info->layer) {
	/* create OGR layer if doesn't exist */
	if (create_ogr_layer(Map, type) < 0)
	    return -1;
    }

    if (!points)
        return 0;

    cat = -1; /* no attributes to be written */
    if (cats->n_cats > 0 && Vect_get_num_dblinks(Map) > 0) {
	/* check for attributes */
	Fi = Vect_get_dblink(Map, 0);
	if (Fi) {
	    if (!Vect_cat_get(cats, Fi->number, &cat))
		G_warning(_("No category defined for layer %d"), Fi->number);
	    if (cats->n_cats > 1) {
		G_warning(_("Feature has more categories, using "
			    "category %d (from layer %d)"),
			  cat, cats->field[0]);
	    }
	}
    }
    
    Ogr_featuredefn = OGR_L_GetLayerDefn(ogr_info->layer);
    Ogr_geom_type = OGR_FD_GetGeomType(Ogr_featuredefn);
    
    /* determine matching OGR feature geometry type */
    if (type & (GV_POINT | GV_KERNEL)) {
	if (Ogr_geom_type != wkbPoint &&
	    Ogr_geom_type != wkbPoint25D) {
	    G_warning(_("Feature is not a point. Skipping."));
	    return -1;
	}
	Ogr_geometry = OGR_G_CreateGeometry(wkbPoint);
    }
    else if (type & GV_LINE) {
	if (Ogr_geom_type != wkbLineString &&
	    Ogr_geom_type != wkbLineString25D) {
	    G_warning(_("Feature is not a line. Skipping."));
	    return -1;
	}
	Ogr_geometry = OGR_G_CreateGeometry(wkbLineString);
    }
    else if (type & GV_BOUNDARY) {
	if (Ogr_geom_type != wkbPolygon) {
	    G_warning(_("Feature is not a polygon. Skipping."));
	    return -1;
	}
	Ogr_geometry = OGR_G_CreateGeometry(wkbPolygon);
    }
    else if (type & GV_FACE) {
	if (Ogr_geom_type != wkbPolygon25D) {
	    G_warning(_("Feature is not a face. Skipping."));
	    return -1;
	}
	Ogr_geometry = OGR_G_CreateGeometry(wkbPolygon25D);
    }
    else {
	G_warning(_("Unsupported feature type (%d)"), type);
	return -1;
    }

    G_debug(3, "V1_write_line_ogr(): type = %d", type);

    if (Ogr_geom_type == wkbPolygon || Ogr_geom_type == wkbPolygon25D) {
	int iring, npoints;
	
        /* add rings (first is exterior ring) */
        for (iring = 0; iring < nparts; iring++) {
            OGRGeometryH Ogr_ring;
            
            points = p_points[iring];
            npoints = points->n_points - 1;
            Ogr_ring = OGR_G_CreateGeometry(wkbLinearRing);
            if (points->x[0] != points->x[npoints] ||
                points->y[0] != points->y[npoints] ||
                points->z[0] != points->z[npoints]) {
                G_warning(_("Boundary is not closed. Feature skipped."));
                return -1;
            }
	
            /* add points */
            for (i = 0; i < npoints; i++) {
                OGR_G_AddPoint(Ogr_ring, points->x[i], points->y[i],
                               points->z[i]);
            }
            G_debug(4, "   ring(%d): n_points = %d", iring, npoints);
            OGR_G_AddGeometry(Ogr_geometry, Ogr_ring);
        }
    }
    else {
	for (i = 0; i < points->n_points; i++) {
	    OGR_G_AddPoint(Ogr_geometry, points->x[i], points->y[i],
			   points->z[i]);
	}
        G_debug(4, "   n_points = %d", points->n_points);
    }
    
    /* create feature & set geometry */
    Ogr_feature = OGR_F_Create(Ogr_featuredefn);
    OGR_F_SetGeometry(Ogr_feature, Ogr_geometry);

    /* write attributes */
    if (cat > -1 && ogr_info->dbdriver) {
	if (0 > write_attributes(ogr_info->dbdriver,
                                 cat, Fi, ogr_info->layer, Ogr_feature))
            G_warning(_("Unable to writes feature attributes"));
	G_free(Fi);
    }
    /* write feature into layer */
    ret = OGR_L_CreateFeature(ogr_info->layer, Ogr_feature);

    /* update offset array */
    if (offset_info->array_num >= offset_info->array_alloc) {
	offset_info->array_alloc += 1000;
	offset_info->array = (int *) G_realloc(offset_info->array,
						offset_info->array_alloc *
						sizeof(int));
    }

    offset = offset_info->array_num;
    
    offset_info->array[offset_info->array_num++] = (int) OGR_F_GetFID(Ogr_feature);
    if (Ogr_geom_type == wkbPolygon || Ogr_geom_type == wkbPolygon25D) {
	/* register exterior ring in offset array */
	offset_info->array[offset_info->array_num++] = 0; 
    }
      
    /* destroy */
    OGR_G_DestroyGeometry(Ogr_geometry);
    OGR_F_Destroy(Ogr_feature);
    
    if (ret != OGRERR_NONE)
	return -1;
    
    G_debug(3, "write_feature(): -> offset = %lu offset_num = %d cat = %d",
	    (unsigned long) offset, offset_info->array_num, cat);

    return offset;
}
Ejemplo n.º 13
0
/*!
   \brief Create new OGR layer in given OGR datasource (internal use only)

   V1_open_new_ogr() is required to be called before this function.

   List of currently supported types:
    - GV_POINT     (wkbPoint)
    - GV_LINE      (wkbLineString)
    - GV_BOUNDARY  (wkb_Polygon)
   \param[in,out] Map pointer to Map_info structure
   \param type feature type (GV_POINT, GV_LINE, ...)

   \return 0 success
   \return -1 error 
*/
int create_ogr_layer(struct Map_info *Map, int type)
{
    int ndblinks;
    OGRLayerH            Ogr_layer;
    OGRSpatialReferenceH Ogr_spatial_ref;
    
    struct field_info *Fi;
    struct Key_Value *projinfo, *projunits;
    struct Format_info_ogr *ogr_info;
    
    OGRwkbGeometryType Ogr_geom_type;
    char             **Ogr_layer_options;
    
    ogr_info = &(Map->fInfo.ogr);
    
    if (!ogr_info->driver_name ||
	!ogr_info->layer_name ||
	!ogr_info->ds)
	return -1;
    
    /* get spatial reference */
    projinfo  = G_get_projinfo();
    projunits = G_get_projunits();
    Ogr_spatial_ref = GPJ_grass_to_osr(projinfo, projunits);
    G_free_key_value(projinfo);
    G_free_key_value(projunits);
    
    /* determine geometry type */
    switch(type) {
    case GV_POINT:
	Ogr_geom_type = wkbPoint;
	break;
    case GV_LINE:
	Ogr_geom_type = wkbLineString;
	break;
    case GV_BOUNDARY:
	Ogr_geom_type = wkbPolygon;
	break;
    default:
	G_warning(_("Unsupported geometry type (%d)"), type);
	return -1;
    }
    
    /* check creation options */
    Ogr_layer_options = ogr_info->layer_options;
    if (Vect_is_3d(Map)) {
	if (strcmp(ogr_info->driver_name, "PostgreSQL") == 0) {
	    Ogr_layer_options = CSLSetNameValue(Ogr_layer_options, "DIM", "3");
	}
    }
    else {
	if (strcmp(ogr_info->driver_name, "PostgreSQL") == 0) {
	    Ogr_layer_options = CSLSetNameValue(Ogr_layer_options, "DIM", "2");
	}
    }

    /* create new OGR layer */
    Ogr_layer = OGR_DS_CreateLayer(ogr_info->ds, ogr_info->layer_name,
				   Ogr_spatial_ref, Ogr_geom_type, Ogr_layer_options);
    CSLDestroy(Ogr_layer_options);
    if (!Ogr_layer) {
	G_warning(_("Unable to create OGR layer <%s> in '%s'"),
		  ogr_info->layer_name, ogr_info->dsn);
	return -1;
    }
    ogr_info->layer = Ogr_layer;

    ndblinks = Vect_get_num_dblinks(Map);
    if (ndblinks > 0) {
	/* write also attributes */
	Fi = Vect_get_dblink(Map, 0);
	if (Fi) {
	    if (ndblinks > 1)
		G_warning(_("More layers defined, using driver <%s> and "
			    "database <%s>"), Fi->driver, Fi->database);
	    ogr_info->dbdriver = create_table(ogr_info->layer, Fi);
	    G_free(Fi);
	}
	else
	  G_warning(_("Database connection not defined. "
		      "Unable to write attributes."));
    }
    
    if (OGR_L_TestCapability(ogr_info->layer, OLCTransactions))
	OGR_L_StartTransaction(ogr_info->layer);

    return 0;
}
Ejemplo n.º 14
0
int main(int argc, char **argv)
{
    int i;
    int **cats, *ncats, nfields, *fields;
    struct Flag *line_flag;

    /* struct Flag *all_flag; */
    struct Option *in_opt, *out_opt;
    struct Flag *table_flag;
    struct GModule *module;
    struct line_pnts *Points;
    struct line_cats *Cats;
    int node, nnodes;
    COOR *coor;
    int ncoor, acoor;
    int line, nlines, type, ctype, area, nareas;
    int err_boundaries, err_centr_out, err_centr_dupl, err_nocentr;

    G_gisinit(argv[0]);

    module = G_define_module();
    G_add_keyword(_("vector"));
    G_add_keyword(_("geometry"));
    G_add_keyword(_("triangulation"));
    module->description = _("Creates a Voronoi diagram from an input vector "
			    "map containing points or centroids.");

    in_opt = G_define_standard_option(G_OPT_V_INPUT);
    out_opt = G_define_standard_option(G_OPT_V_OUTPUT);

    /*
       all_flag = G_define_flag ();
       all_flag->key = 'a';
       all_flag->description = _("Use all points (do not limit to current region)");
     */

    line_flag = G_define_flag();
    line_flag->key = 'l';
    line_flag->description =
	_("Output tessellation as a graph (lines), not areas");

    table_flag = G_define_flag();
    table_flag->key = 't';
    table_flag->description = _("Do not create attribute table");

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


    if (line_flag->answer)
	Type = GV_LINE;
    else
	Type = GV_BOUNDARY;

    All = 0;

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

    /* open files */
    Vect_set_open_level(2);
    Vect_open_old(&In, in_opt->answer, "");

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

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

    /* initialize working region */
    G_get_window(&Window);
    Vect_region_box(&Window, &Box);
    Box.T = 0.5;
    Box.B = -0.5;

    freeinit(&sfl, sizeof(struct Site));

    G_message(_("Reading sites..."));
    readsites();

    siteidx = 0;
    geominit();

    triangulate = 0;
    plot = 0;
    debug = 0;

    G_message(_("Voronoi triangulation..."));
    voronoi(triangulate, nextone);

    /* Close free ends by current region */
    Vect_build_partial(&Out, GV_BUILD_BASE);

    ncoor = 0;
    acoor = 100;
    coor = (COOR *) G_malloc(sizeof(COOR) * acoor);

    nnodes = Vect_get_num_nodes(&Out);
    for (node = 1; node <= nnodes; node++) {
	double x, y;

	if (Vect_get_node_n_lines(&Out, node) < 2) {	/* add coordinates */
	    Vect_get_node_coor(&Out, node, &x, &y, NULL);

	    if (ncoor == acoor - 5) {	/* always space for 5 region corners */
		acoor += 100;
		coor = (COOR *) G_realloc(coor, sizeof(COOR) * acoor);
	    }

	    coor[ncoor].x = x;
	    coor[ncoor].y = y;
	    ncoor++;
	}
    }

    /* Add region corners */
    coor[ncoor].x = Box.W;
    coor[ncoor].y = Box.S;
    ncoor++;
    coor[ncoor].x = Box.E;
    coor[ncoor].y = Box.S;
    ncoor++;
    coor[ncoor].x = Box.E;
    coor[ncoor].y = Box.N;
    ncoor++;
    coor[ncoor].x = Box.W;
    coor[ncoor].y = Box.N;
    ncoor++;

    /* Sort */
    qsort(coor, ncoor, sizeof(COOR), (void *)cmp);

    /* add last (first corner) */
    coor[ncoor].x = Box.W;
    coor[ncoor].y = Box.S;
    ncoor++;

    for (i = 1; i < ncoor; i++) {
	if (coor[i].x == coor[i - 1].x && coor[i].y == coor[i - 1].y)
	    continue;		/* duplicate */

	Vect_reset_line(Points);
	Vect_append_point(Points, coor[i].x, coor[i].y, 0.0);
	Vect_append_point(Points, coor[i - 1].x, coor[i - 1].y, 0.0);
	Vect_write_line(&Out, Type, Points, Cats);
    }

    G_free(coor);

    /* Copy input points as centroids */
    nfields = Vect_cidx_get_num_fields(&In);
    cats = (int **)G_malloc(nfields * sizeof(int *));
    ncats = (int *)G_malloc(nfields * sizeof(int));
    fields = (int *)G_malloc(nfields * sizeof(int));
    for (i = 0; i < nfields; i++) {
	ncats[i] = 0;
	cats[i] =
	    (int *)G_malloc(Vect_cidx_get_num_cats_by_index(&In, i) *
			    sizeof(int));
	fields[i] = Vect_cidx_get_field_number(&In, i);
    }

    if (line_flag->answer)
	ctype = GV_POINT;
    else
	ctype = GV_CENTROID;

    nlines = Vect_get_num_lines(&In);

    G_message(_("Writing sites to output..."));

    for (line = 1; line <= nlines; line++) {

	G_percent(line, nlines, 2);

	type = Vect_read_line(&In, Points, Cats, line);
	if (!(type & GV_POINTS))
	    continue;

	if (!Vect_point_in_box(Points->x[0], Points->y[0], 0.0, &Box))
	    continue;

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


	for (i = 0; i < Cats->n_cats; i++) {
	    int f, j;

	    f = -1;
	    for (j = 0; j < nfields; j++) {	/* find field */
		if (fields[j] == Cats->field[i]) {
		    f = j;
		    break;
		}
	    }
	    if (f > -1) {
		cats[f][ncats[f]] = Cats->cat[i];
		ncats[f]++;
	    }
	}
    }

    /* Copy tables */
    if (!(table_flag->answer)) {
	int ttype, ntabs = 0;
	struct field_info *IFi, *OFi;

	/* Number of output tabs */
	for (i = 0; i < Vect_get_num_dblinks(&In); i++) {
	    int f, j;

	    IFi = Vect_get_dblink(&In, i);

	    f = -1;
	    for (j = 0; j < nfields; j++) {	/* find field */
		if (fields[j] == IFi->number) {
		    f = j;
		    break;
		}
	    }
	    if (f > -1) {
		if (ncats[f] > 0)
		    ntabs++;
	    }
	}

	if (ntabs > 1)
	    ttype = GV_MTABLE;
	else
	    ttype = GV_1TABLE;

	for (i = 0; i < nfields; i++) {
	    int ret;

	    if (fields[i] == 0)
		continue;

	    G_message(_("Layer %d"), fields[i]);

	    /* Make a list of categories */
	    IFi = Vect_get_field(&In, fields[i]);
	    if (!IFi) {		/* no table */
		G_message(_("No table"));
		continue;
	    }

	    OFi =
		Vect_default_field_info(&Out, IFi->number, IFi->name, ttype);

	    ret =
		db_copy_table_by_ints(IFi->driver, IFi->database, IFi->table,
				      OFi->driver,
				      Vect_subst_var(OFi->database, &Out),
				      OFi->table, IFi->key, cats[i],
				      ncats[i]);

	    if (ret == DB_FAILED) {
		G_warning(_("Cannot copy table"));
	    }
	    else {
		Vect_map_add_dblink(&Out, OFi->number, OFi->name, OFi->table,
				    IFi->key, OFi->database, OFi->driver);
	    }
	}
    }


    Vect_close(&In);

    /* cleaning part 1: count errors */
    Vect_build_partial(&Out, GV_BUILD_CENTROIDS);
    err_boundaries = err_centr_out = err_centr_dupl = err_nocentr = 0;
    nlines = Vect_get_num_lines(&Out);
    for (line = 1; line <= nlines; line++) {

	if (!Vect_line_alive(&Out, line))
	    continue;

	type = Vect_get_line_type(&Out, line);
	if (type == GV_BOUNDARY) {
	    int left, right;

	    Vect_get_line_areas(&Out, line, &left, &right);

	    if (left == 0 || right == 0) {
		G_debug(3, "line = %d left = %d right = %d", line, 
			left, right);
		err_boundaries++;
	    }
	}
	if (type == GV_CENTROID) {
	    area = Vect_get_centroid_area(&Out, line);
	    if (area == 0)
		err_centr_out++;
	    else if (area < 0)
		err_centr_dupl++;
	}
    }

    err_nocentr = 0;
    nareas = Vect_get_num_areas(&Out);
    for (area = 1; area <= nareas; area++) {
	if (!Vect_area_alive(&Out, area))
	    continue;
	line = Vect_get_area_centroid(&Out, area);
	if (line == 0)
	    err_nocentr++;
    }

    /* cleaning part 2: snap */
    if (err_nocentr || err_centr_dupl || err_centr_out) {
	int nmod;

	G_important_message(_("Output needs topological cleaning"));
	Vect_snap_lines(&Out, GV_BOUNDARY, 1e-7, NULL);
	do {
	    Vect_break_lines(&Out, GV_BOUNDARY, NULL);
	    Vect_remove_duplicates(&Out, GV_BOUNDARY, NULL);
	    nmod =
		Vect_clean_small_angles_at_nodes(&Out, GV_BOUNDARY, NULL);
	} while (nmod > 0);

	err_boundaries = 0;
	nlines = Vect_get_num_lines(&Out);
	for (line = 1; line <= nlines; line++) {

	    if (!Vect_line_alive(&Out, line))
		continue;

	    type = Vect_get_line_type(&Out, line);
	    if (type == GV_BOUNDARY) {
		int left, right;

		Vect_get_line_areas(&Out, line, &left, &right);

		if (left == 0 || right == 0) {
		    G_debug(3, "line = %d left = %d right = %d", line, 
			    left, right);
		    err_boundaries++;
		}
	    }
	}
    }
    /* cleaning part 3: remove remaining incorrect boundaries */
    if (err_boundaries) {
	G_important_message(_("Removing incorrect boundaries from output"));
	nlines = Vect_get_num_lines(&Out);
	for (line = 1; line <= nlines; line++) {

	    if (!Vect_line_alive(&Out, line))
		continue;

	    type = Vect_get_line_type(&Out, line);
	    if (type == GV_BOUNDARY) {
		int left, right;

		Vect_get_line_areas(&Out, line, &left, &right);

		/* &&, not ||, no typo */
		if (left == 0 && right == 0) {
		    G_debug(3, "line = %d left = %d right = %d", line, 
			    left, right);
		    Vect_delete_line(&Out, line);
		}
	    }
	}
    }

    /* build clean topology */
    Vect_build_partial(&Out, GV_BUILD_NONE);
    Vect_build(&Out);
    Vect_close(&Out);

    G_done_msg(" ");
    exit(EXIT_SUCCESS);
}
Ejemplo n.º 15
0
Archivo: misc.c Proyecto: caomw/grass
/* TODO: The collection of categories is horrible in current version! 
 * Everything repeats many times. We need some data structure
 * implementing set! */
int copy_tables_by_cats(struct Map_info *In, struct Map_info *Out)
{
    /* this is the (mostly) code from v.extract, it should be moved to 
     * some vector library (probably) */

    int nlines, line, nfields;
    int ttype, ntabs = 0;
    struct field_info *IFi, *OFi;
    struct line_cats *Cats;
    int **ocats, *nocats, *fields;
    int i;

    /* Collect list of output cats */
    Cats = Vect_new_cats_struct();
    nfields = Vect_cidx_get_num_fields(In);
    ocats = (int **)G_malloc(nfields * sizeof(int *));
    nocats = (int *)G_malloc(nfields * sizeof(int));
    fields = (int *)G_malloc(nfields * sizeof(int));
    for (i = 0; i < nfields; i++) {
	nocats[i] = 0;
	ocats[i] =
	    (int *)G_malloc(Vect_cidx_get_num_cats_by_index(In, i) *
			    sizeof(int));
	fields[i] = Vect_cidx_get_field_number(In, i);
    }
    nlines = Vect_get_num_lines(Out);
    for (line = 1; line <= nlines; line++) {
	Vect_read_line(Out, NULL, Cats, line);
	for (i = 0; i < Cats->n_cats; i++) {
	    int f = 0, j;

	    for (j = 0; j < nfields; j++) {	/* find field */
		if (fields[j] == Cats->field[i]) {
		    f = j;
		    break;
		}
	    }
	    ocats[f][nocats[f]] = Cats->cat[i];
	    nocats[f]++;
	}
    }

    /* Copy tables */
    G_message(_("Writing attributes..."));

    /* Number of output tabs */
    for (i = 0; i < Vect_get_num_dblinks(In); i++) {
	int j, f = -1;

	IFi = Vect_get_dblink(In, i);

	for (j = 0; j < nfields; j++) {	/* find field */
	    if (fields[j] == IFi->number) {
		f = j;
		break;
	    }
	}
	if (f >= 0 && nocats[f] > 0)
	    ntabs++;
    }

    if (ntabs > 1)
	ttype = GV_MTABLE;
    else
	ttype = GV_1TABLE;

    for (i = 0; i < nfields; i++) {
	int ret;

	if (fields[i] == 0)
	    continue;
	if (nocats[i] == 0)
	    continue;
	/*        if ( fields[i] == field && new_cat != -1 ) continue; */

	G_message(_("Layer %d"), fields[i]);
	/* Make a list of categories */
	IFi = Vect_get_field(In, fields[i]);
	if (!IFi) {		/* no table */
	    G_warning(_("Database connection not defined for layer %d"),
		      fields[i]);
	    continue;
	}

	OFi = Vect_default_field_info(Out, IFi->number, IFi->name, ttype);

	ret = db_copy_table_by_ints(IFi->driver, IFi->database, IFi->table,
				    OFi->driver, Vect_subst_var(OFi->database,
								Out),
				    OFi->table, IFi->key, ocats[i],
				    nocats[i]);

	if (ret == DB_FAILED) {
	    G_warning(_("Unable to copy table <%s>"), IFi->table);
	}
	else {
	    Vect_map_add_dblink(Out, OFi->number, OFi->name, OFi->table,
				IFi->key, OFi->database, OFi->driver);
	}
    }

    for (i = 0; i < nfields; i++)
	G_free(ocats[i]);
    G_free(ocats);
    G_free(nocats);
    G_free(fields);
    return 1;
}
Ejemplo n.º 16
0
/*!
   \brief Copy a map including attribute tables

   Old vector is deleted

   \param in input vector map name
   \param mapset mapset name
   \param out output vector map name

   \return -1 error
   \return 0 success
 */
int Vect_copy(const char *in, const char *mapset, const char *out)
{
    int i, n, ret, type;
    struct Map_info In, Out;
    struct field_info *Fi, *Fin;
    char old_path[GPATH_MAX], new_path[GPATH_MAX], buf[GPATH_MAX];
    const char *files[] = { GV_FRMT_ELEMENT, GV_COOR_ELEMENT,
	GV_HEAD_ELEMENT, GV_HIST_ELEMENT,
	GV_TOPO_ELEMENT, GV_SIDX_ELEMENT, GV_CIDX_ELEMENT,
	NULL
    };
    const char *inmapset;
    char xname[GNAME_MAX], xmapset[GMAPSET_MAX];

    dbDriver *driver;

    G_debug(2, "Copy vector '%s' in '%s' to '%s'", in, mapset, out);
    /* check for [A-Za-z][A-Za-z0-9_]* in name */
    if (Vect_legal_filename(out) < 0)
	G_fatal_error(_("Vector map name is not SQL compliant"));

    inmapset = G_find_vector2(in, mapset);
    if (!inmapset) {
	G_warning(_("Unable to find vector map <%s> in <%s>"), in, mapset);
	return -1;
    }
    mapset = inmapset;

    /* remove mapset from fully qualified name, confuses G_file_name() */
    if (G_name_is_fully_qualified(in, xname, xmapset)) {
	in = xname;
    }

    /* Delete old vector if it exists */
    if (G_find_vector2(out, G_mapset())) {
	G_warning(_("Vector map <%s> already exists and will be overwritten"),
		  out);
	ret = Vect_delete(out);
	if (ret != 0) {
	    G_warning(_("Unable to delete vector map <%s>"), out);
	    return -1;
	}
    }

    /* Copy the directory */
    G__make_mapset_element(GV_DIRECTORY);
    sprintf(buf, "%s/%s", GV_DIRECTORY, out);
    G__make_mapset_element(buf);

    i = 0;
    while (files[i]) {
	sprintf(buf, "%s/%s", in, files[i]);
	G_file_name(old_path, GV_DIRECTORY, buf, mapset);
	sprintf(buf, "%s/%s", out, files[i]);
	G_file_name(new_path, GV_DIRECTORY, buf, G_mapset());

	if (access(old_path, F_OK) == 0) {	/* file exists? */
	    G_debug(2, "copy %s to %s", old_path, new_path);
	    if (copy_file(old_path, new_path)) {
		G_warning(_("Unable to copy vector map <%s> to <%s>"),
			  old_path, new_path);
	    }
	}
	i++;
    }

    G_file_name(old_path, GV_DIRECTORY, in, mapset);
    G_file_name(new_path, GV_DIRECTORY, out, G_mapset());

    /* Open input */
    Vect_set_open_level(1);
    Vect_open_old_head(&In, in, mapset);

    if (In.format != GV_FORMAT_NATIVE) {	/* Done */
	Vect_close(&In);
	return 0;
    }

    /* Open output */
    Vect_set_open_level(1);
    Vect_open_update_head(&Out, out, G_mapset());

    /* Copy tables */
    n = Vect_get_num_dblinks(&In);
    type = GV_1TABLE;
    if (n > 1)
	type = GV_MTABLE;
    for (i = 0; i < n; i++) {
	Fi = Vect_get_dblink(&In, i);
	if (Fi == NULL) {
	    G_warning(_("Database connection not defined for layer %d"),
		      In.dblnk->field[i].number);
	    Vect_close(&In);
	    Vect_close(&Out);
	    return -1;
	}
	Fin = Vect_default_field_info(&Out, Fi->number, Fi->name, type);
	G_debug(3, "Copy drv:db:table '%s:%s:%s' to '%s:%s:%s'",
		Fi->driver, Fi->database, Fi->table, Fin->driver,
		Fin->database, Fin->table);

	Vect_map_add_dblink(&Out, Fi->number, Fi->name, Fin->table, Fi->key,
			    Fin->database, Fin->driver);

	ret = db_copy_table(Fi->driver, Fi->database, Fi->table,
			    Fin->driver, Vect_subst_var(Fin->database, &Out),
			    Fin->table);
	if (ret == DB_FAILED) {
	    G_warning(_("Unable to copy table <%s>"), Fin->table);
	    Vect_close(&In);
	    Vect_close(&Out);
	    return -1;
	}

	driver =
	    db_start_driver_open_database(Fin->driver,
					  Vect_subst_var(Fin->database,
							 &Out));
	if (driver == NULL) {
	    G_warning(_("Unable to open database <%s> by driver <%s>"),
		      Fin->database, Fin->driver);
	}
	else {
	    if (db_create_index2(driver, Fin->table, Fi->key) != DB_OK)
		G_warning(_("Unable to create index for table <%s>, key <%s>"),
			  Fi->table, Fi->key);

	    db_close_database_shutdown_driver(driver);
	}
    }

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

    return 0;
}
Ejemplo n.º 17
0
void print_info(const struct Map_info *Map)
{
    int i;
    char line[100];
    char tmp1[100], tmp2[100];

    struct bound_box box;
    
    divider('+');
    if (Vect_maptype(Map) & (GV_FORMAT_OGR | GV_FORMAT_OGR_DIRECT)) {
	/* for OGR format print also datasource and layer */
	sprintf(line, "%-17s%s", _("OGR layer:"),
		Vect_get_ogr_layer_name(Map));
	printline(line);
	sprintf(line, "%-17s%s", _("OGR datasource:"),
		Vect_get_ogr_dsn_name(Map));
	printline(line);
    }
    else {
	sprintf(line, "%-17s%s", _("Name:"),
		Vect_get_name(Map));
	printline(line);
	sprintf(line, "%-17s%s", _("Mapset:"),
		Vect_get_mapset(Map));
	printline(line);
    }

    sprintf(line, "%-17s%s", _("Location:"),
	    G_location());
    printline(line);
    sprintf(line, "%-17s%s", _("Database:"),
	    G_gisdbase());
    printline(line);
    sprintf(line, "%-17s%s", _("Title:"),
	    Vect_get_map_name(Map));
    printline(line);
    sprintf(line, "%-17s1:%d", _("Map scale:"),
	    Vect_get_scale(Map));
    printline(line);
    
    if (Vect_maptype(Map) & (GV_FORMAT_OGR | GV_FORMAT_OGR_DIRECT)) {
	sprintf(line, "%-17s%s (%s)", _("Map format:"),
		Vect_maptype_info(Map), Vect_get_ogr_format_info(Map));
    }
    else {
	sprintf(line, "%-17s%s", _("Map format:"),
		Vect_maptype_info(Map));
    }
    
    printline(line);
    sprintf(line, "%-17s%s", _("Name of creator:"),
	    Vect_get_person(Map));
    printline(line);
    sprintf(line, "%-17s%s", _("Organization:"),
	    Vect_get_organization(Map));
    printline(line);
    sprintf(line, "%-17s%s", _("Source date:"),
	    Vect_get_map_date(Map));
    printline(line);
    
    divider('|');
    
    sprintf(line, "  %s: %s (%s: %i)",
	    _("Type of map"), _("vector"), _("level"), Vect_level(Map));
    
    printline(line);
    
    if (Vect_level(Map) > 0) {
	printline("");
	sprintf(line,
		"  %-24s%-9d       %-22s%-9d",
		_("Number of points:"), 
		Vect_get_num_primitives(Map, GV_POINT),
		_("Number of centroids:"),
		Vect_get_num_primitives(Map, GV_CENTROID));
	printline(line);
	sprintf(line,
		"  %-24s%-9d       %-22s%-9d",
		_("Number of lines:"),
		Vect_get_num_primitives(Map, GV_LINE),
		_("Number of boundaries:"),
		Vect_get_num_primitives(Map, GV_BOUNDARY));
	printline(line);
	sprintf(line,
		"  %-24s%-9d       %-22s%-9d",
		_("Number of areas:"),
		Vect_get_num_areas(Map),
		_("Number of islands:"),
		Vect_get_num_islands(Map));
	printline(line);
	if (Vect_is_3d(Map)) {
	    sprintf(line,
		    "  %-24s%-9d       %-22s%-9d",
		    _("Number of faces:"),
		    Vect_get_num_primitives(Map, GV_FACE),
		    _("Number of kernels:"),
		    Vect_get_num_primitives(Map, GV_KERNEL));
	    printline(line);
	    sprintf(line,
		    "  %-24s%-9d       %-22s%-9d",
		    _("Number of volumes:"),
		    Vect_get_num_volumes(Map),
		    _("Number of holes:"),
		    Vect_get_num_holes(Map));
	    printline(line);
	}
	printline("");
	
	sprintf(line, "  %-24s%s",
		_("Map is 3D:"),
		Vect_is_3d(Map) ? _("Yes") : _("No"));
	printline(line);
	sprintf(line, "  %-24s%-9d",
		_("Number of dblinks:"),
		Vect_get_num_dblinks(Map));
	printline(line);
    }
    
    printline("");
    /* this differs from r.info in that proj info IS taken from the map here, not the location settings */
    /* Vect_get_proj_name() and _zone() are typically unset?! */
    if (G_projection() == PROJECTION_UTM)
	sprintf(line, "  %s: %s (%s %d)",
		_("Projection:"),
		Vect_get_proj_name(Map),
		_("zone"), Vect_get_zone(Map));
    else
	sprintf(line, "  %s: %s",
		_("Projection"),
		Vect_get_proj_name(Map));
    
    printline(line);
    printline("");
    
    Vect_get_map_box(Map, &box);
    
    G_format_northing(box.N, tmp1, G_projection());
    G_format_northing(box.S, tmp2, G_projection());
    sprintf(line, "              %c: %17s    %c: %17s",
	    'N', tmp1, 'S', tmp2);
    printline(line);
    
    G_format_easting(box.E, tmp1, G_projection());
    G_format_easting(box.W, tmp2, G_projection());
    sprintf(line, "              %c: %17s    %c: %17s",
	    'E', tmp1, 'W', tmp2);
    printline(line);
    
    if (Vect_is_3d(Map)) {
	format_double(box.B, tmp1);
	format_double(box.T, tmp2);
	sprintf(line, "              %c: %17s    %c: %17s",
		'B', tmp1, 'T', tmp2);
	printline(line);
    }
    printline("");

    format_double(Vect_get_thresh(Map), tmp1);
    sprintf(line, "  %s: %s", _("Digitization threshold"), tmp1);
    printline(line);
    sprintf(line, "  %s:", _("Comment"));
    printline(line);
    sprintf(line, "    %s", Vect_get_comment(Map));
    printline(line);
    divider('+');
    fprintf(stdout, "\n");
}
Ejemplo n.º 18
0
/*!
   \brief Rename a map.

   Attribute tables are created in the same database where input tables were stored.

   The original format (native/OGR) is used.
   Old map ('out') is deleted!!!

   \param in input vector map name
   \param out output vector map name

   \return -1 error
   \return 0 success
 */
int Vect_rename(const char *in, const char *out)
{
    int i, n, ret, type;
    struct Map_info Map;
    struct field_info *Fin, *Fout;
    int *fields;
    dbDriver *driver;
    char xname[GNAME_MAX], xmapset[GMAPSET_MAX];

    G_debug(2, "Rename vector '%s' to '%s'", in, out);
    /* check for [A-Za-z][A-Za-z0-9_]* in name */
    if (Vect_legal_filename(out) < 0)
	G_fatal_error(_("Vector map name is not SQL compliant"));

    /* Delete old vector if it exists */
    if (G_find_vector2(out, G_mapset())) {
	G_warning(_("Vector map <%s> already exists and will be overwritten"),
		  out);
	Vect_delete(out);
    }

    /* remove mapset from fully qualified name */
    if (G_name_is_fully_qualified(in, xname, xmapset)) {
	in = xname;
    }

    /* Move the directory */
    ret = G_rename(GV_DIRECTORY, in, out);

    if (ret == 0) {
	G_warning(_("Vector map <%s> not found"), in);
	return -1;
    }
    else if (ret == -1) {
	G_warning(_("Unable to copy vector map <%s> to <%s>"), in, out);
	return -1;
    }

    /* Rename all tables if the format is native */
    Vect_set_open_level(1);
    Vect_open_update_head(&Map, out, G_mapset());

    if (Map.format != GV_FORMAT_NATIVE) {	/* Done */
	Vect_close(&Map);
	return 0;
    }

    /* Copy tables */
    n = Vect_get_num_dblinks(&Map);
    type = GV_1TABLE;
    if (n > 1)
	type = GV_MTABLE;

    /* Make the list of fields */
    fields = (int *)G_malloc(n * sizeof(int));

    for (i = 0; i < n; i++) {
	Fin = Vect_get_dblink(&Map, i);
	fields[i] = Fin->number;
    }

    for (i = 0; i < n; i++) {
	G_debug(3, "field[%d] = %d", i, fields[i]);

	Fin = Vect_get_field(&Map, fields[i]);
	if (Fin == NULL) {
	    G_warning(_("Database connection not defined for layer %d"),
		      fields[i]);
	    Vect_close(&Map);
	    return -1;
	}

	Fout = Vect_default_field_info(&Map, Fin->number, Fin->name, type);
	G_debug(3, "Copy drv:db:table '%s:%s:%s' to '%s:%s:%s'",
		Fin->driver, Fin->database, Fin->table, Fout->driver,
		Fout->database, Fout->table);

	/* TODO: db_rename_table instead of db_copy_table */
	ret = db_copy_table(Fin->driver, Fin->database, Fin->table,
			    Fout->driver, Vect_subst_var(Fout->database,
							 &Map), Fout->table);

	if (ret == DB_FAILED) {
	    G_warning(_("Unable to copy table <%s>"), Fin->table);
	    Vect_close(&Map);
	    return -1;
	}

	/* Change the link */
	Vect_map_del_dblink(&Map, Fin->number);

	Vect_map_add_dblink(&Map, Fout->number, Fout->name, Fout->table,
			    Fin->key, Fout->database, Fout->driver);

	/* Delete old table */
	ret = db_delete_table(Fin->driver, Fin->database, Fin->table);
	if (ret == DB_FAILED) {
	    G_warning(_("Unable to delete table <%s>"), Fin->table);
	    Vect_close(&Map);
	    return -1;
	}

	driver =
	    db_start_driver_open_database(Fout->driver,
					  Vect_subst_var(Fout->database,
							 &Map));
	if (driver == NULL) {
	    G_warning(_("Unable to open database <%s> by driver <%s>"),
		      Fout->database, Fout->driver);
	}
	else {
	    if (db_create_index2(driver, Fout->table, Fin->key) != DB_OK)
		G_warning(_("Unable to create index for table <%s>, key <%s>"),
			  Fout->table, Fout->key);

	    db_close_database_shutdown_driver(driver);
	}
    }

    Vect_close(&Map);
    free(fields);

    return 0;
}
Ejemplo n.º 19
0
Archivo: main.c Proyecto: 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);
}
Ejemplo n.º 20
0
void copy_tabs(struct Map_info *In, struct Map_info *Out,
	       int nfields, int *fields, int *ncats, int **cats)
{
    int i, ttype, ntabs;

    struct field_info *IFi, *OFi;
    
    ntabs = 0;
    
    G_message(_("Writing attributes..."));
    
    /* Number of output tabs */
    for (i = 0; i < Vect_get_num_dblinks(In); i++) {
	int f, j;
	
	IFi = Vect_get_dblink(In, i);
	
	for (j = 0; j < nfields; j++) {	/* find field */
	    if (fields[j] == IFi->number) {
		f = j;
		break;
	    }
	}
	if (ncats[f] > 0)
	    ntabs++;
    }
    
    if (ntabs > 1)
	ttype = GV_MTABLE;
    else
	ttype = GV_1TABLE;
    
    for (i = 0; i < nfields; i++) {
	int ret;

	if (fields[i] == 0)
	    continue;
	
	/* Make a list of categories */
	IFi = Vect_get_field(In, fields[i]);
	if (!IFi) {		/* no table */
	    G_warning(_("No table for layer %d"), fields[i]);
	    continue;
	}
	
	OFi =
	    Vect_default_field_info(Out, IFi->number, IFi->name, ttype);
	
	ret =
	    db_copy_table_by_ints(IFi->driver, IFi->database, IFi->table,
				  OFi->driver,
				  Vect_subst_var(OFi->database, Out),
				  OFi->table, IFi->key, cats[i],
				  ncats[i]);
	
	if (ret == DB_FAILED) {
	    G_warning(_("Unable to copy table for layer %d"), fields[i]);
	}
	else {
	    Vect_map_add_dblink(Out, OFi->number, OFi->name, OFi->table,
				IFi->key, OFi->database, OFi->driver);
	}
    }
}