Ejemplo n.º 1
0
/**
   \brief Select features by category
 
   \param[in] Map vector map
   \param[in] cl_orig original list of categories (previously selected)
   \param[in] layer layer number
   \param[in] type feature type
   \param[in] cat category string
   \param[in,out] List list of selected features

   \return number of selected lines
*/
int sel_by_cat(struct Map_info *Map, struct cat_list *cl_orig,
	       int layer, int type, char *cats, struct ilist *List)
{
    struct ilist *List_tmp, *List_tmp1;
    struct cat_list *cl;

    int i, cat;

    if (first_selection || cl_orig) {
	List_tmp = List;
	first_selection = 0;
    }
    else {
	List_tmp = Vect_new_list();
    }

    List_tmp1 = Vect_new_list();

    if (cl_orig == NULL) {
	cl = Vect_new_cat_list();

	Vect_str_to_cat_list(cats, cl);
    }
    else {
	cl = cl_orig;
    }

    for (i = 0; i < cl->n_ranges; i++) {
	for (cat = cl->min[i]; cat <= cl->max[i]; cat++) {
	    Vect_cidx_find_all(Map, layer, type, cat, List_tmp1);
	    Vect_list_append_list(List_tmp, List_tmp1);
	}
    }

    G_debug(1, "  %d lines selected (by category)", List_tmp->n_values);

    /* merge lists (only duplicate items) */
    if (List_tmp != List) {
	merge_lists(List, List_tmp);
	Vect_destroy_list(List_tmp);
    }

    Vect_destroy_list(List_tmp1);

    return List->n_values;
}
Ejemplo n.º 2
0
int find_node(struct Map_info *Pnts, int field, int cat)
{
    static struct ilist *list;

    if (!list)
	list = Vect_new_list();

    /* find start node */
    Vect_cidx_find_all(Pnts, field, GV_POINT, cat, list);
    if (list->n_values < 1) {
	G_warning(_("No point with category %d found"), cat);
	return 0;
    }
    if (list->n_values > 1) {
	G_warning(_("More points with category %d found"), cat);
	return 0;
    }

    return list->value[0];
}
Ejemplo n.º 3
0
int main(int argc, char **argv)
{
    struct GModule *module;
    struct Option *map_opt, *field_opt, *fs_opt, *vs_opt, *nv_opt, *col_opt,
	*where_opt, *file_opt;
    struct Flag *c_flag, *v_flag, *r_flag;
    dbDriver *driver;
    dbString sql, value_string;
    dbCursor cursor;
    dbTable *table;
    dbColumn *column;
    dbValue *value;
    struct field_info *Fi;
    int ncols, col, more;
    struct Map_info Map;
    char query[1024];
    struct ilist *list_lines;

    struct bound_box *min_box, *line_box;
    int i, line, area, init_box, cat;

    module = G_define_module();
    G_add_keyword(_("vector"));
    G_add_keyword(_("database"));
    G_add_keyword(_("attribute table"));
    module->description = _("Prints vector map attributes.");

    map_opt = G_define_standard_option(G_OPT_V_MAP);
    field_opt = G_define_standard_option(G_OPT_V_FIELD);

    col_opt = G_define_standard_option(G_OPT_DB_COLUMNS);

    where_opt = G_define_standard_option(G_OPT_DB_WHERE);

    fs_opt = G_define_standard_option(G_OPT_F_SEP);
    fs_opt->description = _("Output field separator");
    fs_opt->guisection = _("Format");

    vs_opt = G_define_standard_option(G_OPT_F_SEP);
    vs_opt->key = "vs";
    vs_opt->description = _("Output vertical record separator");
    vs_opt->answer = NULL;
    vs_opt->guisection = _("Format");

    nv_opt = G_define_option();
    nv_opt->key = "nv";
    nv_opt->type = TYPE_STRING;
    nv_opt->required = NO;
    nv_opt->description = _("Null value indicator");
    nv_opt->guisection = _("Format");

    file_opt = G_define_standard_option(G_OPT_F_OUTPUT); 
    file_opt->key = "file";
    file_opt->required = NO; 
    file_opt->description = 
	_("Name for output file (if omitted or \"-\" output to stdout)"); 
    
    r_flag = G_define_flag();
    r_flag->key = 'r';
    r_flag->description =
	_("Print minimal region extent of selected vector features instead of attributes");

    c_flag = G_define_flag();
    c_flag->key = 'c';
    c_flag->description = _("Do not include column names in output");
    c_flag->guisection = _("Format");

    v_flag = G_define_flag();
    v_flag->key = 'v';
    v_flag->description = _("Vertical output (instead of horizontal)");
    v_flag->guisection = _("Format");

    G_gisinit(argv[0]);

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

    /* set input vector map name and mapset */
    if (file_opt->answer && strcmp(file_opt->answer, "-") != 0) { 
	if (NULL == freopen(file_opt->answer, "w", stdout)) { 
	    G_fatal_error(_("Unable to open file <%s> for writing"), file_opt->answer); 
	} 
    } 
    
    if (r_flag->answer) {
	min_box = (struct bound_box *) G_malloc(sizeof(struct bound_box));
	G_zero((void *)min_box, sizeof(struct bound_box));

	line_box = (struct bound_box *) G_malloc(sizeof(struct bound_box));
	list_lines = Vect_new_list();
    }
    else {
      min_box = line_box = NULL;
      list_lines = NULL;
    }

    db_init_string(&sql);
    db_init_string(&value_string);

    /* open input vector */
    if (!r_flag->answer)
	Vect_open_old_head2(&Map, map_opt->answer, "", field_opt->answer);
    else {
	if (2 > Vect_open_old2(&Map, map_opt->answer, "", field_opt->answer)) {
	    Vect_close(&Map);
	    G_fatal_error(_("Unable to open vector map <%s> at topology level. "
			   "Flag '%c' requires topology level."),
			  map_opt->answer, r_flag->key);
	}
    }

    if ((Fi = Vect_get_field2(&Map, field_opt->answer)) == NULL)
	G_fatal_error(_("Database connection not defined for layer <%s>"),
		      field_opt->answer);

    driver = db_start_driver_open_database(Fi->driver, Fi->database);

    if (!driver)
	G_fatal_error(_("Unable to open database <%s> by driver <%s>"),
		      Fi->database, Fi->driver);

    if (col_opt->answer)
	sprintf(query, "SELECT %s FROM ", col_opt->answer);
    else
	sprintf(query, "SELECT * FROM ");

    db_set_string(&sql, query);
    db_append_string(&sql, Fi->table);

    if (where_opt->answer) {
	char *buf = NULL;

	buf = G_malloc((strlen(where_opt->answer) + 8));
	sprintf(buf, " WHERE %s", where_opt->answer);
	db_append_string(&sql, buf);
	G_free(buf);
    }

    if (db_open_select_cursor(driver, &sql, &cursor, DB_SEQUENTIAL) != DB_OK)
	G_fatal_error(_("Unable to open select cursor"));

    table = db_get_cursor_table(&cursor);
    ncols = db_get_table_number_of_columns(table);

    /* column names if horizontal output (ignore for -r) */
    if (!v_flag->answer && !c_flag->answer && !r_flag->answer) {
	for (col = 0; col < ncols; col++) {
	    column = db_get_table_column(table, col);
	    if (col)
		fprintf(stdout, "%s", fs_opt->answer);
	    fprintf(stdout, "%s", db_get_column_name(column));
	}
	fprintf(stdout, "\n");
    }

    init_box = 1;

    /* fetch the data */
    while (1) {
	if (db_fetch(&cursor, DB_NEXT, &more) != DB_OK)
	    G_fatal_error(_("Unable to fetch data from table <%s>"),
			  Fi->table);

	if (!more)
	    break;

	cat = -1;
	for (col = 0; col < ncols; col++) {
	    column = db_get_table_column(table, col);
	    value = db_get_column_value(column);

	    if (cat < 0 && strcmp(Fi->key, db_get_column_name(column)) == 0) {
		cat = db_get_value_int(value);
		if (r_flag->answer)
		    break;
	    }

	    if (r_flag->answer)
		continue;

	    db_convert_column_value_to_string(column, &value_string);

	    if (!c_flag->answer && v_flag->answer)
		fprintf(stdout, "%s%s", db_get_column_name(column),
			fs_opt->answer);

	    if (col && !v_flag->answer)
		fprintf(stdout, "%s", fs_opt->answer);

	    if (nv_opt->answer && db_test_value_isnull(value))
		fprintf(stdout, "%s", nv_opt->answer);
	    else
		fprintf(stdout, "%s", db_get_string(&value_string));

	    if (v_flag->answer)
		fprintf(stdout, "\n");
	}

	if (r_flag->answer) {
	    /* get minimal region extent */
	    Vect_cidx_find_all(&Map, Vect_get_field_number(&Map, field_opt->answer), -1, cat, list_lines);
	    for (i = 0; i < list_lines->n_values; i++) {
		line = list_lines->value[i];
		area = Vect_get_centroid_area(&Map, line);
		if (area > 0) {
		    if (!Vect_get_area_box(&Map, area, line_box))
			G_fatal_error(_("Unable to get bounding box of area %d"),
				      area);
		}
		else {
		    if (!Vect_get_line_box(&Map, line, line_box))
			G_fatal_error(_("Unable to get bounding box of line %d"),
				      line);
		}
		if (init_box) {
		    Vect_box_copy(min_box, line_box);
		    init_box = 0;
		}
		else {
		    Vect_box_extend(min_box, line_box);
		}
	    }
	}
	else {
	    if (!v_flag->answer)
		fprintf(stdout, "\n");
	    else if (vs_opt->answer)
		fprintf(stdout, "%s\n", vs_opt->answer);
	}
    }

    if (r_flag->answer) {
	fprintf(stdout, "n=%f\n", min_box->N);
	fprintf(stdout, "s=%f\n", min_box->S);
	fprintf(stdout, "w=%f\n", min_box->W);
	fprintf(stdout, "e=%f\n", min_box->E);
	if (Vect_is_3d(&Map)) {
	    fprintf(stdout, "t=%f\n", min_box->T);
	    fprintf(stdout, "b=%f\n", min_box->B);
	}
	fflush(stdout);

	G_free((void *)min_box);
	G_free((void *)line_box);

	Vect_destroy_list(list_lines);
    }

    db_close_cursor(&cursor);
    db_close_database_shutdown_driver(driver);
    Vect_close(&Map);

    exit(EXIT_SUCCESS);
}
Ejemplo n.º 4
0
int export_areas_multi(struct Map_info *In, int field, int donocat,
                       OGRFeatureDefnH Ogr_featuredefn,OGRLayerH Ogr_layer,
                       struct field_info *Fi, dbDriver *driver, int ncol, int *colctype,
                       const char **colname, int doatt, int nocat,
                       int *n_noatt, int *n_nocat)
{
    int i, n_exported, area;
    int cat, ncats_field, line, type, findex, ipart;

    struct line_pnts *Points;
    struct line_cats *Cats;
    struct ilist *cat_list, *line_list, *lcats;

    OGRGeometryH Ogr_geometry, Ogr_geometry_part;
    OGRFeatureH Ogr_feature;
    OGRwkbGeometryType wkbtype, wkbtype_part;
    
    Points = Vect_new_line_struct();
    Cats = Vect_new_cats_struct();
    cat_list = Vect_new_list();
    line_list = Vect_new_list();
    lcats = Vect_new_list();

    n_exported = 0;

    /* check if category index is available for given field */
    findex = Vect_cidx_get_field_index(In, field);
    if (findex == -1)
        G_fatal_error(_("Unable to export multi-features. No category index for layer %d."),
                      field);
    
    /* determine type */
    wkbtype_part = wkbPolygon;
    wkbtype = get_multi_wkbtype(wkbtype_part);
    
    ncats_field = Vect_cidx_get_unique_cats_by_index(In, findex, cat_list);
    G_debug(1, "n_cats = %d for layer %d", ncats_field, field);

    if (donocat)
	G_message(_("Exporting features with category..."));

    for (i = 0; i < cat_list->n_values; i++) {
        G_percent(i, cat_list->n_values - 1, 5);

        cat = cat_list->value[i];
        /* find all centroids with given category */
        Vect_cidx_find_all(In, field, GV_CENTROID, cat, line_list);

        /* create multi-feature */
        Ogr_geometry = OGR_G_CreateGeometry(wkbtype);

        /* build simple features geometry, go through all parts */
        for (ipart = 0; ipart < line_list->n_values; ipart++) {
            line = line_list->value[ipart];
            G_debug(3, "cat=%d, line=%d -> part=%d", cat, line, ipart);

            /* get centroid's category */
            Vect_read_line(In, NULL, Cats, line);
            /* check for category consistency */
            Vect_field_cat_get(Cats, field, lcats);
	    if (!Vect_val_in_list(lcats, cat))
                G_fatal_error(_("Unable to create multi-feature. "
                                "Category %d not found in line %d, field %d"),
                              cat, line, field);
            
            /* find correspoding area */
            area = Vect_get_centroid_area(In, line);
            if (area == 0)
                continue;
                
            /* create polygon from area */
            Ogr_geometry_part = create_polygon(In, area, Points);

            /* add part */
            OGR_G_AddGeometryDirectly(Ogr_geometry, Ogr_geometry_part);
        }

        if (!OGR_G_IsEmpty(Ogr_geometry)) {
            /* write multi-feature */
            Ogr_feature = OGR_F_Create(Ogr_featuredefn);
            OGR_F_SetGeometry(Ogr_feature, Ogr_geometry);
            
            mk_att(cat, Fi, driver, ncol, colctype, colname, doatt, nocat,
                   Ogr_feature, n_noatt);
            OGR_L_CreateFeature(Ogr_layer, Ogr_feature);

            OGR_F_Destroy(Ogr_feature);

            n_exported++;
        }
        else {
            /* skip empty features */
            G_debug(3, "multi-feature is empty -> skipped");
        }
        
        OGR_G_DestroyGeometry(Ogr_geometry);
    }

    if (donocat)
	G_message(_("Exporting features without category..."));

    /* check lines without category, if -c flag is given write them as
     * one multi-feature */
    Ogr_geometry = OGR_G_CreateGeometry(wkbtype);
    
    Vect_rewind(In);
    Vect_set_constraint_type(In, GV_CENTROID);
    while(TRUE) {
        type = Vect_read_next_line(In, NULL, Cats);
        if (type < 0)
            break;

        /* get centroid's category */
        Vect_cat_get(Cats, field, &cat);
        if (cat > 0)
            continue; /* skip features with category */
        if (cat < 0 && !donocat) {
            (*n_nocat)++;
            continue; /* skip lines without category, do not export
                       * not labeled */
        }

        /* find correspoding area */
	line = Vect_get_next_line_id(In);
        area = Vect_get_centroid_area(In, line);
        if (area == 0)
            continue;
                
        /* create polygon from area */
        Ogr_geometry_part = create_polygon(In, area, Points);
        
        /* add part */
        OGR_G_AddGeometryDirectly(Ogr_geometry, Ogr_geometry_part);

        (*n_nocat)++;
    }

    if (!OGR_G_IsEmpty(Ogr_geometry)) {
        /* write multi-feature */
        Ogr_feature = OGR_F_Create(Ogr_featuredefn);
        OGR_F_SetGeometry(Ogr_feature, Ogr_geometry);
        
        mk_att(cat, Fi, driver, ncol, colctype, colname, doatt, nocat,
               Ogr_feature, n_noatt);
        OGR_L_CreateFeature(Ogr_layer, Ogr_feature);

        OGR_F_Destroy(Ogr_feature);
        
        n_exported++;
    }
    else {
        /* skip empty features */
        G_debug(3, "multi-feature is empty -> skipped");
    }
    
    OGR_G_DestroyGeometry(Ogr_geometry);
    
    Vect_destroy_line_struct(Points);
    Vect_destroy_cats_struct(Cats);
    Vect_destroy_list(cat_list);
    Vect_destroy_list(line_list);
    Vect_destroy_list(lcats);
    
    return n_exported;
}