コード例 #1
0
ファイル: do_areas.c プロジェクト: rashadkm/grass_cmake
int sort_areas(struct Map_info *Map, struct line_pnts *Points,
               int field, struct cat_list *cat_list)
{
    int i, centroid, nareas_selected;
    struct line_cats *Cats;
    CELL cat;

    G_begin_polygon_area_calculations();
    Cats = Vect_new_cats_struct();

    /* first count valid areas */
    nareas = Vect_get_num_areas(Map);
    if (nareas == 0)
	return 0;

    /* allocate list to hold valid area info */
    list =
	(struct list *)G_calloc(nareas * sizeof(char), sizeof(struct list));

    /* store area size,cat,index in list */
    nareas_selected = 0;
    for (i = 0; i < nareas; i++) {

	centroid = Vect_get_area_centroid(Map, i + 1);
	SETNULL(&cat);
	if (centroid <= 0) {
	    G_debug(2,_("Area without centroid (OK for island)"));
	}
	else {
	    Vect_read_line(Map, NULL, Cats, centroid);
	    if (field > 0) {
		if (Vect_cats_in_constraint(Cats, field, cat_list)) {
		    Vect_cat_get(Cats, field, &cat);
		    nareas_selected++;
		}
		else {
		    G_debug(2, _("Area centroid without category"));
		}
	    }
	    else {
		/* field < 1, process all areas with centroid */
		cat = 0;
		nareas_selected++;
	    }
	}

	list[i].index = i + 1;
	Vect_get_area_points(Map, i + 1, Points);
	list[i].size =
	    G_area_of_polygon(Points->x, Points->y, Points->n_points);

	list[i].cat = cat;
    }
    if (nareas_selected > 0) {
	/* sort the list by size */
	qsort(list, nareas * sizeof(char), sizeof(struct list), compare);
    }

    return nareas_selected;
}
コード例 #2
0
ファイル: sites.c プロジェクト: imincik/pkg-grass
/*-
 * Reads ptr and returns 0 on success,
 *                      -1 on EOF,
 *                      -2 on other fatal error or insufficient data,
 *                       1 on format mismatch (extra data)
 */
int G_site_get(struct Map_info *Map, Site * s)
{
    int i, type, cat;
    static struct line_pnts *Points = NULL;
    static struct line_cats *Cats = NULL;
    SITE_ATT *sa;

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

    while (1) {
	type = Vect_read_next_line(Map, Points, Cats);

	if (type == -1)
	    return -2;		/* Error */
	if (type == -2)
	    return -1;		/* EOF */
	if (type != GV_POINT)
	    continue;		/* Is not point */

	Vect_cat_get(Cats, 1, &cat);

	G_debug(4, "Site: %f|%f|%f|#%d", Points->x[0], Points->y[0],
		Points->z[0], cat);

	s->east = Points->x[0];
	s->north = Points->y[0];
	if (Vect_is_3d(Map))
	    s->dim[0] = Points->z[0];

	s->ccat = cat;

	/* find att */

	if (Map->n_site_att > 0) {
	    sa = (SITE_ATT *) bsearch((void *)&cat, (void *)Map->site_att,
				      Map->n_site_att, sizeof(SITE_ATT),
				      site_att_cmp);

	    if (sa == NULL) {
		G_warning(_("Attributes for category %d not found"), cat);
		for (i = 0; i < Map->n_site_dbl; i++)
		    s->dbl_att[i] = 0;
		for (i = 0; i < Map->n_site_str; i++)
		    G_strncpy(s->str_att[i], "", MAX_SITE_STRING);
	    }
	    else {
		for (i = 0; i < Map->n_site_dbl; i++)
		    s->dbl_att[i] = sa->dbl[i];
		for (i = 0; i < Map->n_site_str; i++)
		    G_strncpy(s->str_att[i], sa->str[i], MAX_SITE_STRING);
	    }
	}

	return 0;
    }
}
コード例 #3
0
ファイル: utils.c プロジェクト: AsherBond/MondocosmOS
/*!
   \brief Get node cost

   For each node in the map, finds the category of the point on it (if
   there is any) and stores the value associated with this category in
   the array node_costs. If there is no point with a category,
   node_costs=0.

   node_costs are multiplied by 1000000 and truncated to integers (as
   is done in Vect_net_build_graph)

   \param In pointer to Map_info structure
   \param layer layer number
   \param column name of column
   \param[out] node_costs list of node costs

   \returns 1 on success
   \return 0 on failure
 */
int NetA_get_node_costs(struct Map_info *In, int layer, char *column,
			int *node_costs)
{
    int i, nlines, nnodes;
    dbCatValArray vals;
    struct line_cats *Cats;
    struct line_pnts *Points;

    dbDriver *driver;
    struct field_info *Fi;

    Fi = Vect_get_field(In, layer);
    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);

    nlines = Vect_get_num_lines(In);
    nnodes = Vect_get_num_nodes(In);
    Cats = Vect_new_cats_struct();
    Points = Vect_new_line_struct();
    for (i = 1; i <= nnodes; i++)
	node_costs[i] = 0;

    db_CatValArray_init(&vals);

    if (db_select_CatValArray(driver, Fi->table, Fi->key, column, NULL, &vals)
	== -1)
	return 0;
    for (i = 1; i <= nlines; i++) {
	int type = Vect_read_line(In, Points, Cats, i);

	if (type == GV_POINT) {
	    int node, cat;
	    double value;

	    if (!Vect_cat_get(Cats, layer, &cat))
		continue;
	    Vect_get_line_nodes(In, i, &node, NULL);
	    if (db_CatValArray_get_value_double(&vals, cat, &value) == DB_OK)
		node_costs[node] = value * 1000000.0;
	}
    }

    Vect_destroy_cats_struct(Cats);
    db_CatValArray_free(&vals);
    db_close_database_shutdown_driver(driver);
    return 1;
}
コード例 #4
0
ファイル: line.c プロジェクト: caomw/grass
/*!
  \brief Fetches FIRST category number for given vector line and field
  
  \param Map pointer to Map_info structure
  \param line line id
  \param field layer number

  \return -1 no category
  \return category number (>=0)
 */
int Vect_get_line_cat(const struct Map_info *Map, int line, int field)
{

    static struct line_cats *cats = NULL;
    int cat, ltype;

    if (cats == NULL)
	cats = Vect_new_cats_struct();

    ltype = Vect_read_line(Map, NULL, cats, line);
    Vect_cat_get(cats, field, &cat);
    G_debug(3, "Vect_get_line_cat: display line %d, ltype %d, cat %d", line,
	    ltype, cat);

    return cat;
}
コード例 #5
0
ファイル: ascii.c プロジェクト: rashadkm/grass_cmake
/* check category */
int get_cat(const struct line_cats *Cats, const struct cat_list *Clist,
	      const int *cats, int ncats, int field, int *cat)
{
    int i;
    
    *cat = -1;
    
    if (field < 1)
	return TRUE;
    
    if (Clist && Clist->field == field) {
	for (i = 0; i < Cats->n_cats; i++) {
	    if (Cats->field[i] == field &&
		Vect_cat_in_cat_list(Cats->cat[i], Clist)) {
		*cat = Cats->cat[i];
		return TRUE;
	    }
	}
	return FALSE;
    }
    if (cats) {
	int *found;

	for (i = 0; i < Cats->n_cats; i++) {
	    if (Cats->field[i] == field) {
		found = (int *)bsearch((void *) &(Cats->cat[i]), cats, 
		                       ncats, sizeof(int), srch);
		if (found) {
		    /* found */
		    *cat = *found;
		    return TRUE;
		}
	    }
	}
	return FALSE;
    }
    if (!Clist && !cats && field > 0) {
	Vect_cat_get(Cats, field, cat);
	if (*cat > -1)
	    return TRUE;
    }
    
    return FALSE;
}
コード例 #6
0
ファイル: shape.c プロジェクト: felipebetancur/grass-ci
int get_cat_color(int line, const struct line_cats *Cats, const struct cat_list *Clist,
		  int *red, int *grn, int *blu)
{
    int custom_rgb;
    unsigned char which;
    int cat;
    
    custom_rgb = FALSE;
    if (Clist->field > 0) {
	Vect_cat_get(Cats, Clist->field, &cat);
	if (cat >= 0) {
	    G_debug(3, "display element %d, cat %d", line, cat);
	    /* fetch color number from category */
	    which = (cat % palette_ncolors);
	    G_debug(3, "cat:%d which color:%d r:%d g:%d b:%d", cat,
		    which, palette[which].R, palette[which].G,
		    palette[which].B);
	    
	    custom_rgb = TRUE;
	    *red = palette[which].R;
	    *grn = palette[which].G;
	    *blu = palette[which].B;
	}
    }
    else if (Cats->n_cats > 0) {
	/* fetch color number from layer */
	which = (Cats->field[0] % palette_ncolors);
	G_debug(3, "layer:%d which color:%d r:%d g:%d b:%d",
		Cats->field[0], which, palette[which].R,
		palette[which].G, palette[which].B);
	
	custom_rgb = TRUE;
	*red = palette[which].R;
	*grn = palette[which].G;
	*blu = palette[which].B;
    }

    return custom_rgb;
}
コード例 #7
0
ファイル: write_ogr.c プロジェクト: AsherBond/MondocosmOS
/*!
  \brief Writes feature on level 1 (OGR interface)

  \param Map pointer to Map_info structure
  \param type feature type
  \param points pointer to line_pnts structure (feature geometry)
  \param cats pointer to line_cats structure (feature categories)

  \return feature offset into file
  \return -1 on error
*/
off_t V1_write_line_ogr(struct Map_info *Map, int type,
                        const struct line_pnts *points,
                        const struct line_cats *cats)
{
    int i, cat, ret;

    struct field_info *Fi;
    struct Format_info_ogr *fInfo;

    OGRGeometryH       Ogr_geometry;
    OGRFeatureH        Ogr_feature;
    OGRFeatureDefnH    Ogr_featuredefn;
    OGRwkbGeometryType Ogr_geom_type;

    if (!Map->fInfo.ogr.layer) {
        if (V2_open_new_ogr(Map, type) < 0)
            return -1;
    }

    cat = -1; /* no attributes to be written */
    if (cats->n_cats > 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]);
            }
        }
    }

    fInfo = &(Map->fInfo.ogr);
    Ogr_featuredefn = OGR_L_GetLayerDefn(fInfo->layer);
    Ogr_geom_type = OGR_FD_GetGeomType(Ogr_featuredefn);

    /* determine matching OGR feature geometry type */
    /* NOTE: centroids are not supported in OGR,
     *       pseudotopo holds virtual centroids */
    /* NOTE: boundaries are not supported in OGR,
     *       pseudotopo treats polygons as boundaries */

    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) {
        /* create exterior ring */
        OGRGeometryH Ogr_ring;
        int npoints;

        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. Skipping."));
            return -1;
        }

        /* add points */
        for (i = 0; i < points->n_points; i++) {
            OGR_G_AddPoint(Ogr_ring, points->x[i], points->y[i],
                           points->z[i]);
        }
        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 && fInfo->dbdriver) {
        write_attributes(fInfo->dbdriver,
                         cat, Fi, fInfo->layer, Ogr_feature);
        G_free(Fi);
    }
    /* write feature into layer */
    ret = OGR_L_CreateFeature(fInfo->layer, Ogr_feature);

    /* update offset array */
    if (fInfo->offset_num >= fInfo->offset_alloc) {
        fInfo->offset_alloc += 1000;
        fInfo->offset = (int *) G_realloc(fInfo->offset,
                                          fInfo->offset_alloc *
                                          sizeof(int));
    }
    /* how to deal with OGRNullFID ? */
    fInfo->offset[fInfo->offset_num] = (int)OGR_F_GetFID(Ogr_feature);

    /* destroy */
    OGR_G_DestroyGeometry(Ogr_geometry);
    OGR_F_Destroy(Ogr_feature);

    if (ret != OGRERR_NONE)
        return -1;

    return fInfo->offset_num++;
}
コード例 #8
0
ファイル: export_areas.c プロジェクト: rashadkm/grass_cmake
int export_areas_single(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, j;
    int centroid, cat, area, n_areas;
    int n_exported;
    
    struct line_pnts *Points;
    struct line_cats *Cats;

    OGRGeometryH Ogr_geometry;
    OGRFeatureH Ogr_feature;

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

    n_exported = 0;

    n_areas = Vect_get_num_areas(In);
    for (i = 1; i <= n_areas; i++) {
        G_percent(i, n_areas, 5);
        
        /* get centroid's category */
        centroid = Vect_get_area_centroid(In, i);
        cat = -1;
        if (centroid > 0) {
            Vect_read_line(In, NULL, Cats, centroid);
            Vect_cat_get(Cats, field, &cat);
        }
        G_debug(3, "area = %d centroid = %d ncats = %d", i, centroid,
                Cats->n_cats);
        if (cat < 0 && !donocat) {
            (*n_nocat)++;
            continue; /* skip areas without category, do not export
                       * not labeled */
        }
        
        /* find correspoding area */
        area = Vect_get_centroid_area(In, centroid);
        if (area == 0)
            continue;

        /* create polygon from area */
        Ogr_geometry = create_polygon(In, area, Points);

        /* add feature */
        Ogr_feature = OGR_F_Create(Ogr_featuredefn);
        OGR_F_SetGeometry(Ogr_feature, Ogr_geometry);
        
        /* output one feature for each category */
        for (j = -1; j < Cats->n_cats; j++) {
            if (j == -1) {
                if (cat >= 0)
                    continue;	/* cat(s) exists */
		(*n_nocat)++;
            }
            else {
                if (Cats->field[j] == field)
                    cat = Cats->cat[j];
                else
                    continue;
            }
            
            mk_att(cat, Fi, driver, ncol, colctype, colname, doatt, nocat,
                   Ogr_feature, n_noatt);
            OGR_L_CreateFeature(Ogr_layer, Ogr_feature);
            
            n_exported++;
        }
        OGR_G_DestroyGeometry(Ogr_geometry);
        OGR_F_Destroy(Ogr_feature);
    }

    Vect_destroy_line_struct(Points);
    Vect_destroy_cats_struct(Cats);

    return n_exported;
}
コード例 #9
0
ファイル: export_areas.c プロジェクト: rashadkm/grass_cmake
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;
}
コード例 #10
0
ファイル: zones.c プロジェクト: GRASS-GIS/grass-ci
struct Point *P_Read_Vector_Region_Map(struct Map_info *Map,
				       struct Cell_head *Elaboration,
				       int *num_points, int dim_vect,
				       int layer)
{
    int line_num, pippo, npoints, cat, type;
    double x, y, z;
    struct Point *obs;
    struct line_pnts *points;
    struct line_cats *categories;
    struct bound_box elaboration_box;

    pippo = dim_vect;
    obs = (struct Point *)G_calloc(pippo, sizeof(struct Point));

    points = Vect_new_line_struct();
    categories = Vect_new_cats_struct();

    /* Reading points inside elaboration zone */
    Vect_region_box(Elaboration, &elaboration_box);

    npoints = 0;
    line_num = 0;

    Vect_rewind(Map);
    while ((type = Vect_read_next_line(Map, points, categories)) > 0) {

	if (!(type & GV_POINT))
	    continue;

	line_num++;

	x = points->x[0];
	y = points->y[0];
	if (points->z != NULL)
	    z = points->z[0];
	else
	    z = 0.0;

	/* Reading and storing points only if in elaboration_reg */
	if (Vect_point_in_box(x, y, z, &elaboration_box)) {
	    npoints++;
	    if (npoints >= pippo) {
		pippo += dim_vect;
		obs =
		    (struct Point *)G_realloc((void *)obs,
					      (signed int)pippo *
					      sizeof(struct Point));
	    }

	    /* Storing observation vector */
	    obs[npoints - 1].coordX = x;
	    obs[npoints - 1].coordY = y;
	    obs[npoints - 1].coordZ = z;
	    obs[npoints - 1].lineID = line_num;	/* Storing also the line's number */

	    Vect_cat_get(categories, layer, &cat);
	    obs[npoints - 1].cat = cat;
	}
    }
    Vect_destroy_line_struct(points);
    Vect_destroy_cats_struct(categories);

    *num_points = npoints;
    return obs;
}
コード例 #11
0
ファイル: query.c プロジェクト: rashadkm/grass_cmake
int query(struct Map_info *Map)
{
    int i, j, idx, cat_no, nlines, type;
    register int line_num;
    struct line_pnts *Points;
    struct line_cats *Cats;
    struct field_info *Fi;
    dbString stmt, value_string;
    dbDriver *driver;

    /* Initialize the Point struct */
    Points = Vect_new_line_struct();
    Cats = Vect_new_cats_struct();

    G_message(_("Reading features..."));

    /* Cycle through all lines and make a list of categories of 'qfield' for each category given by 'field' */
    nlines = Vect_get_num_lines(Map);
    for (line_num = 1; line_num <= nlines; line_num++) {
	type = Vect_read_line(Map, Points, Cats, line_num);
	if (!(type & options.type))
	    continue;

	for (i = 0; i < Cats->n_cats; i++) {
	    if (Cats->field[i] == options.field) {

		cat_no = Cats->cat[i];

		idx = find_cat(cat_no, 1);

		for (j = 0; j < Cats->n_cats; j++) {
		    if (Cats->field[j] == options.qfield) {	/* Add to list */
			if (Values[idx].nqcats == Values[idx].aqcats) {	/* Alloc space */
			    Values[idx].aqcats += 2;
			    Values[idx].qcat =
				(int *)G_realloc(Values[idx].qcat,
						 Values[idx].aqcats *
						 sizeof(int));
			}
			Values[idx].qcat[Values[idx].nqcats] = Cats->cat[j];
			Values[idx].nqcats++;
		    }
		}
	    }
	}

	/* If there is no field cat add cat -1, values for cat -1 are reported at the end  */
	Vect_cat_get(Cats, options.field, &cat_no);

	if (cat_no == -1) {
	    idx = find_cat(cat_no, 1);

	    for (j = 0; j < Cats->n_cats; j++) {
		if (Cats->field[j] == options.qfield) {	/* Add to list */
		    if (Values[idx].nqcats == Values[idx].aqcats) {	/* Alloc space */
			Values[idx].aqcats += 2;
			Values[idx].qcat =
			    (int *)G_realloc(Values[idx].qcat,
					     Values[idx].aqcats *
					     sizeof(int));
		    }
		    Values[idx].qcat[Values[idx].nqcats] = Cats->cat[j];
		    Values[idx].nqcats++;
		}
	    }
	}

	G_percent(line_num, nlines, 2);
    }

    db_init_string(&stmt);
    db_init_string(&value_string);

    if ((Fi = Vect_get_field(Map, options.qfield)) == NULL)
	G_fatal_error(_("Database connection not defined for layer %d. Use v.db.connect first."),
		      options.qfield);

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

    /* Query the database for each category */
    G_message(_("Querying database... "));
    for (i = 0; i < vstat.rcat; i++) {
	int j, ctype, nrows, more;
	char buf[2000];
	dbCursor cursor;
	dbTable *table;
	dbColumn *column;
	dbValue *value;

	G_debug(3, "cat %d", Values[i].cat);
	G_percent(i + 1, vstat.rcat, 1);

	/* Skip if cat is zero and large number of query categories (many features without category).
	 * It would cause problems on server side and take long time. Postgres limit is 10000 */
	/* TODO: verify because no category is encoded as cat = -1, not cat = zero */
	if (Values[i].cat == 0 && Values[i].nqcats > 1000) {
	    G_warning(_("Query for category '0' (no category) was not executed because of too many "
		       "(%d) query categories. All later reported values for cat 0 are not valid."),
		      Values[i].nqcats);
	    continue;
	}

	if (Values[i].nqcats > 0) {
	    sprintf(buf, "SELECT %s FROM %s WHERE", options.qcol, Fi->table);
	    db_set_string(&stmt, buf);

	    for (j = 0; j < Values[i].nqcats; j++) {
		G_debug(4, "  qcat %d", Values[i].qcat[j]);

		if (j > 0)
		    db_append_string(&stmt, " OR");

		sprintf(buf, " %s = %d", Fi->key, Values[i].qcat[j]);
		db_append_string(&stmt, buf);
	    }
	    G_debug(4, "  SQL: '%s'", db_get_string(&stmt));

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

	    table = db_get_cursor_table(&cursor);
	    column = db_get_table_column(table, 0);	/* first column */
	    value = db_get_column_value(column);
	    ctype = db_sqltype_to_Ctype(db_get_column_sqltype(column));
	    vstat.qtype = ctype;
	    nrows = db_get_num_rows(&cursor);

	    G_debug(4, "  nrows = %d, columnt type = %d", nrows, ctype);

	    if (nrows != 1) {
		if (nrows > 1) {
		    G_warning(_("Multiple query results, output value set to NULL (category [%d])"),
			      Values[i].cat);
		}
		Values[i].null = 1;
	    }
	    else {
		if (db_fetch(&cursor, DB_NEXT, &more) != DB_OK)
		    G_fatal_error(_("Unable to fetch record"));

		db_convert_column_value_to_string(column, &stmt);
		G_debug(4, "  value = %s", db_get_string(&stmt));

		if (db_test_value_isnull(value)) {
		    Values[i].null = 1;
		}
		else {
		    switch (ctype) {
		    case (DB_C_TYPE_INT):
			Values[i].i1 = db_get_value_int(value);
			break;
		    case (DB_C_TYPE_DOUBLE):
			Values[i].d1 = db_get_value_double(value);
			break;
		    case (DB_C_TYPE_STRING):
			Values[i].str1 = G_store(db_get_value_string(value));
			break;
		    case (DB_C_TYPE_DATETIME):
			db_convert_column_value_to_string(column,
							  &value_string);
			Values[i].str1 =
			    G_store(db_get_string(&value_string));
		    }
		    Values[i].null = 0;
		}
	    }
	    db_close_cursor(&cursor);
	}
	else {			/* no qcats -> upload NULL */
	    Values[i].null = 1;
	}
    }

    db_close_database_shutdown_driver(driver);

    return 0;
}
コード例 #12
0
ファイル: label.c プロジェクト: felipebetancur/grass-ci
int process_line(int ltype, const struct line_pnts *Points,
		 const struct line_cats *Cats, LATTR *lattr,
		 int chcat, const struct cat_list *Clist)
{
    int i, cat, len;
    char *text = NULL, buf[100];
    
    D_RGB_color(lattr->color.R, lattr->color.G, lattr->color.B);
    D_text_size(lattr->size, lattr->size);
    if (lattr->font)
	D_font(lattr->font);
    if (lattr->enc)
	D_encoding(lattr->enc);
    
    if (chcat) {
	int found = 0;
	
	for (i = 0; i < Cats->n_cats; i++) {
	    if (Cats->field[i] == Clist->field &&
		Vect_cat_in_cat_list(Cats->cat[i], Clist)) {
		found = 1;
		break;
	    }
	}
	if (!found)
	    return 0;
    }
    else if (Clist->field > 0) {
	int found = 0;
	
	for (i = 0; i < Cats->n_cats; i++) {
	    if (Cats->field[i] == Clist->field) {
		found = 1;
		break;
	    }
	}
	/* lines with no category will be displayed */
	if (Cats->n_cats > 0 && !found)
	    return 0;
    }
    
    if (Vect_cat_get(Cats, lattr->field, &cat)) {
	for (i = 0; i < Cats->n_cats; i++) {
	    G_debug(3, "cat lab: field = %d, cat = %d", Cats->field[i],
		    Cats->cat[i]);
	    if (Cats->field[i] == lattr->field) {	/* all cats of given lfield */
		if (!text) {
		    sprintf(buf, "%d", Cats->cat[i]);
		    text = G_calloc(strlen(buf), sizeof(char));
		    text[0] = '\0';
		    strcpy(text, buf);
		}
		else {
		    sprintf(buf, "/%d", Cats->cat[i]);
		    len = strlen(text) + strlen(buf) + 1;
		    text = G_realloc(text, len * sizeof(char));
		    strcat(text, buf);
		}
	    }
	}
	show_label_line(Points, ltype, lattr, text);
    }
    
    if (text)
	G_free(text);

    return 1;
}
コード例 #13
0
ファイル: main.c プロジェクト: rkrug/grass-ci
int main(int argc, char *argv[])
{
    struct Map_info In, Out;
    static struct line_pnts *Points;
    struct line_cats *Cats;
    struct GModule *module;	/* GRASS module for parsing arguments */
    struct Option *map_in, *map_out;
    struct Option *method_opt, *afield_opt, *nfield_opt, *abcol,
                  *afcol, *ncol;
    struct Flag *add_f;
    int with_z;
    int afield, nfield, mask_type;
    dglGraph_s *graph;
    int *component, nnodes, type, i, nlines, components, max_cat;
    char buf[2000], *covered;
    char *desc;

    /* Attribute table */
    dbString sql;
    dbDriver *driver;
    struct field_info *Fi;

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

    /* initialize module */
    module = G_define_module();
    G_add_keyword(_("vector"));
    G_add_keyword(_("network"));
    G_add_keyword(_("components"));
    module->description =
	_("Computes strongly and weakly connected components in the network.");

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

    afield_opt = G_define_standard_option(G_OPT_V_FIELD);
    afield_opt->key = "arc_layer";
    afield_opt->answer = "1";
    afield_opt->label = _("Arc layer");
    afield_opt->guisection = _("Cost");

    nfield_opt = G_define_standard_option(G_OPT_V_FIELD);
    nfield_opt->key = "node_layer";
    nfield_opt->answer = "2";
    nfield_opt->label = _("Node layer");
    nfield_opt->guisection = _("Cost");

    afcol = G_define_standard_option(G_OPT_DB_COLUMN);
    afcol->key = "arc_column";
    afcol->required = NO;
    afcol->description =
	_("Arc forward/both direction(s) cost column (number)");
    afcol->guisection = _("Cost");

    abcol = G_define_standard_option(G_OPT_DB_COLUMN);
    abcol->key = "arc_backward_column";
    abcol->required = NO;
    abcol->description = _("Arc backward direction cost column (number)");
    abcol->guisection = _("Cost");

    ncol = G_define_option();
    ncol->key = "node_column";
    ncol->type = TYPE_STRING;
    ncol->required = NO;
    ncol->description = _("Node cost column (number)");
    ncol->guisection = _("Cost");

    map_out = G_define_standard_option(G_OPT_V_OUTPUT);

    method_opt = G_define_option();
    method_opt->key = "method";
    method_opt->type = TYPE_STRING;
    method_opt->required = YES;
    method_opt->multiple = NO;
    method_opt->options = "weak,strong";
    desc = NULL;
    G_asprintf(&desc,
	       "weak;%s;strong;%s",
	       _("Weakly connected components"),
	       _("Strongly connected components"));
    method_opt->descriptions = desc;
    method_opt->description = _("Type of components");

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

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

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

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

    Vect_set_open_level(2);

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

    with_z = Vect_is_3d(&In);

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

    /* parse filter option and select appropriate lines */
    afield = Vect_get_field_number(&In, afield_opt->answer);
    nfield = Vect_get_field_number(&In, nfield_opt->answer);

    if (0 != Vect_net_build_graph(&In, mask_type, afield, nfield, afcol->answer,
                                  abcol->answer, ncol->answer, 0, 2))
        G_fatal_error(_("Unable to build graph for vector map <%s>"), Vect_get_full_name(&In));

    graph = Vect_net_get_graph(&In);
    nnodes = Vect_get_num_nodes(&In);
    component = (int *)G_calloc(nnodes + 1, sizeof(int));
    covered = (char *)G_calloc(nnodes + 1, sizeof(char));
    if (!component || !covered) {
	G_fatal_error(_("Out of memory"));
	exit(EXIT_FAILURE);
    }
    /* Create table */
    Fi = Vect_default_field_info(&Out, 1, NULL, GV_1TABLE);
    Vect_map_add_dblink(&Out, 1, NULL, Fi->table, GV_KEY_COLUMN, Fi->database,
			Fi->driver);
    db_init_string(&sql);
    driver = db_start_driver_open_database(Fi->driver, Fi->database);
    if (driver == NULL)
	G_fatal_error(_("Unable to open database <%s> by driver <%s>"),
		      Fi->database, Fi->driver);

    sprintf(buf, "create table %s ( cat integer, comp integer)", Fi->table);

    db_set_string(&sql, buf);
    G_debug(2, "%s", db_get_string(&sql));

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

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

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

    db_begin_transaction(driver);

    if (method_opt->answer[0] == 'w') {
	G_message(_("Computing weakly connected components..."));
	components = NetA_weakly_connected_components(graph, component);
    }
    else {
	G_message(_("Computing strongly connected components..."));
	components = NetA_strongly_connected_components(graph, component);
    }

    G_debug(3, "Components: %d", components);

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

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

    nlines = Vect_get_num_lines(&In);
    max_cat = 1;
    G_percent(0, nlines, 4);
    for (i = 1; i <= nlines; i++) {
	int comp, cat;

	G_percent(i, nlines, 4);
	type = Vect_read_line(&In, Points, Cats, i);
	if (!Vect_cat_get(Cats, afield, &cat))
	    continue;
	if (type == GV_LINE || type == GV_BOUNDARY) {
	    int node1, node2;

	    Vect_get_line_nodes(&In, i, &node1, &node2);
	    if (component[node1] == component[node2]) {
		comp = component[node1];
	    }
	    else {
		continue;
	    }
	}
	else if (type == GV_POINT) {
	    int node;

	    /* Vect_get_line_nodes(&In, i, &node, NULL); */
	    node = Vect_find_node(&In, Points->x[0], Points->y[0], Points->z[0], 0, 0);
	    if (!node)
		continue;
	    comp = component[node];
	    covered[node] = 1;
	}
	else
	    continue;
	
	cat = max_cat++;
	Vect_reset_cats(Cats);
	Vect_cat_set(Cats, 1, cat);
	Vect_write_line(&Out, type, Points, Cats);
	insert_new_record(driver, Fi, &sql, cat, comp);
    }

    /*add points on nodes not covered by any point in the network */
    if (add_f->answer) {
	for (i = 1; i <= nnodes; i++)
	    if (!covered[i]) {
		Vect_reset_cats(Cats);
		Vect_cat_set(Cats, 1, max_cat);
		NetA_add_point_on_node(&In, &Out, i, Cats);
		insert_new_record(driver, Fi, &sql, max_cat++, component[i]);
	    }
    }

    db_commit_transaction(driver);
    db_close_database_shutdown_driver(driver);

    Vect_close(&In);

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

    G_done_msg(_("Found %d components."), components);

    exit(EXIT_SUCCESS);
}
コード例 #14
0
ファイル: trans2.c プロジェクト: rashadkm/grass_cmake
/*!
   \brief transform 2d vector features to 3d

   \param In input vector
   \param Out output vector
   \param type feature type to be transformed
   \param height fixed height (used only if column is NULL)
   \param field layer number
   \param column attribute column used for height
 */
void trans2d(struct Map_info *In, struct Map_info *Out, int type,
	    double height, const char *field_name, const char *column)
{
    int i, ltype, line, field;
    int cat;
    int ret, ctype;

    struct line_pnts *Points;
    struct line_cats *Cats;

    dbCatValArray cvarr;

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

    db_CatValArray_init(&cvarr);

    field = Vect_get_field_number(In, field_name);
    
    if (column) {
	struct field_info *Fi;

	dbDriver *driver;

        if (field == -1) {
            G_warning(_("Invalid layer number %d, assuming 1"), field);
            field = 1;
        }

	Fi = Vect_get_field(In, field);
	if (!Fi) {
	    G_fatal_error(_("Database connection not defined for layer <%s>"),
                          field_name);
	}

	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);
	}
        db_set_error_handler_driver(driver);
        
	/* column type must numeric */
	ctype = db_column_Ctype(driver, Fi->table, column);
	if (ctype == -1) {
	    G_fatal_error(_("Column <%s> not found in table <%s>"),
                          column, Fi->table);
	}
	if (ctype != DB_C_TYPE_INT && ctype != DB_C_TYPE_DOUBLE) {
	    G_fatal_error(_("Column must be numeric"));
	}

        G_message(_("Fetching height from <%s> column..."), column);
	db_select_CatValArray(driver, Fi->table, Fi->key,
			      column, NULL, &cvarr);

	G_debug(3, "%d records selected", cvarr.n_values);

	db_close_database_shutdown_driver(driver);
    }

    G_message(_("Transforming features..."));
    line = 1;
    while (1) {
	ltype = Vect_read_next_line(In, Points, Cats);
	if (ltype == -1) {
	    G_fatal_error(_("Unable to read vector map"));
	}
	if (ltype == -2) {	/* EOF */
	    break;
	}

        G_progress(line, 1000);
        
	if (!(ltype & type))
	    continue;

	if (field != -1 && !Vect_cat_get(Cats, field, &cat))
	    continue;
	
	if (column) {
	    Vect_cat_get(Cats, field, &cat);
	    if (cat < 0) {
		G_warning(_("Skipping feature without category"));
		continue;
	    }

	    if (ctype == DB_C_TYPE_DOUBLE)
		ret = db_CatValArray_get_value_double(&cvarr, cat, &height);
	    else {		/* integer */

		int height_i;

		ret = db_CatValArray_get_value_int(&cvarr, cat, &height_i);
		height = (double)height_i;
	    }

	    if (ret != DB_OK)
		G_warning(_("Unable to get height for feature category %d"),
			  cat);
	}

	for (i = 0; i < Points->n_points; i++) {
	    Points->z[i] = height;
	}

	Vect_write_line(Out, ltype, Points, Cats);

	line++;
    }
    G_progress(1, 1);
    
    Vect_destroy_line_struct(Points);
    Vect_destroy_cats_struct(Cats);
}
コード例 #15
0
ファイル: main.c プロジェクト: rashadkm/grass_cmake
int add_plines(struct Map_info *Map, int field, double textsize)
{
    int nlines, line, nlines_dxf;
    struct line_pnts *Points;
    struct line_cats *Cats;
    char *layer, *llayer;
    int cat;
    char cat_num[50];

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

    nlines = Vect_get_num_lines(Map);
    nlines_dxf = 0;
    for (line = 1; line <= nlines; line++) {
	int i, ltype;

	G_percent(line, nlines, 2);

	ltype = Vect_read_line(Map, Points, Cats, line);
	Vect_cat_get(Cats, field, &cat);
	if (field != -1 && cat < 0)
	    continue;
	
	sprintf(cat_num, "%d", cat);

	if (ltype == GV_POINT) {
	    layer = "point";
	    llayer = "point_label";
	}
	else if (ltype == GV_LINE) {
	    layer = "line";
	}
	else if (ltype == GV_BOUNDARY) {
	    layer = "boundary";
	}
	else if (ltype == GV_CENTROID) {
	    layer = "centroid";
	    llayer = "centroid_label";
	}
	else
	    continue;

	if (ltype & GV_POINTS) {
	    dxf_point(layer, Points->x[0], Points->y[0], Points->z[0]);

	    dxf_text(llayer, Points->x[0], Points->y[0], Points->z[0],
		     textsize, CENTERED, cat_num);
	}
	else {			/* lines */
	    dxf_polyline(layer);

	    for (i = 0; i < Points->n_points; i++)
		dxf_vertex(layer, Points->x[i], Points->y[i], Points->z[i]);

	    dxf_poly_end(layer);
	}
	nlines_dxf++;
    }

    return nlines_dxf;
}
コード例 #16
0
ファイル: main.c プロジェクト: caomw/grass
int main(int argc, char **argv)
{
    int i, j, ret, centre, line, centre1, centre2, tfield, tucfield;
    int nlines, nnodes, type, ltype, afield, nfield, geo, cat;
    int node, node1, node2;
    double cost, e1cost, e2cost, n1cost, n2cost, s1cost, s2cost, l, l1;
    struct Option *map, *output;
    struct Option *afield_opt, *nfield_opt, *afcol, *abcol, *ncol, *type_opt,
	*term_opt, *cost_opt, *tfield_opt, *tucfield_opt;
    struct Flag *geo_f, *turntable_f;
    struct GModule *module;
    struct Map_info Map, Out;
    struct cat_list *catlist;
    CENTER *Centers = NULL;
    int acentres = 0, ncentres = 0;
    NODE *Nodes;
    struct line_cats *Cats;
    struct line_pnts *Points, *SPoints;
    int niso, aiso;
    double *iso;
    int npnts1, apnts1 = 0, npnts2, apnts2 = 0;
    ISOPOINT *pnts1 = NULL, *pnts2 = NULL;
    int next_iso;

    G_gisinit(argv[0]);

    module = G_define_module();
    G_add_keyword(_("vector"));
    G_add_keyword(_("network"));
    G_add_keyword(_("isolines"));
    module->label = _("Splits net by cost isolines.");
    module->description =
	_
	("Splits net to bands between cost isolines (direction from center). "
	 "Center node must be opened (costs >= 0). "
	 "Costs of center node are used in calculation.");

    map = G_define_standard_option(G_OPT_V_INPUT);
    output = G_define_standard_option(G_OPT_V_OUTPUT);

    term_opt = G_define_standard_option(G_OPT_V_CATS);
    term_opt->key = "ccats";
    term_opt->required = YES;
    term_opt->description =
	_("Categories of centers (points on nodes) to which net "
	  "will be allocated, "
	  "layer for this categories is given by nlayer option");

    cost_opt = G_define_option();
    cost_opt->key = "costs";
    cost_opt->type = TYPE_INTEGER;
    cost_opt->multiple = YES;
    cost_opt->required = YES;
    cost_opt->description = _("Costs for isolines");

    afield_opt = G_define_standard_option(G_OPT_V_FIELD);
    afield_opt->key = "alayer";
    afield_opt->answer = "1";
    afield_opt->required = YES;
    afield_opt->label = _("Arc layer");

    type_opt = G_define_standard_option(G_OPT_V_TYPE);
    type_opt->options = "line,boundary";
    type_opt->answer = "line,boundary";
    type_opt->required = YES;
    type_opt->label = _("Arc type");

    nfield_opt = G_define_standard_option(G_OPT_V_FIELD);
    nfield_opt->key = "nlayer";
    nfield_opt->answer = "2";
    nfield_opt->required = YES;
    nfield_opt->label = _("Node layer");

    afcol = G_define_standard_option(G_OPT_DB_COLUMN);
    afcol->key = "afcolumn";
    afcol->description =
	_("Arc forward/both direction(s) cost column (number)");
    afcol->guisection = _("Cost");

    abcol = G_define_standard_option(G_OPT_DB_COLUMN);
    abcol->key = "abcolumn";
    abcol->description = _("Arc backward direction cost column (number)");
    abcol->guisection = _("Cost");

    ncol = G_define_standard_option(G_OPT_DB_COLUMN);
    ncol->key = "ncolumn";
    ncol->description = _("Node cost column (number)");
    ncol->guisection = _("Cost");

    turntable_f = G_define_flag();
    turntable_f->key = 't';
    turntable_f->description = _("Use turntable");
    turntable_f->guisection = _("Turntable");

    tfield_opt = G_define_standard_option(G_OPT_V_FIELD);
    tfield_opt->key = "tlayer";
    tfield_opt->answer = "3";
    tfield_opt->label = _("Layer with turntable");
    tfield_opt->description =
	_("Relevant only with -t flag");
    tfield_opt->guisection = _("Turntable");

    tucfield_opt = G_define_standard_option(G_OPT_V_FIELD);
    tucfield_opt->key = "tuclayer";
    tucfield_opt->answer = "4";
    tucfield_opt->label = _("Layer with unique categories used in turntable");
    tucfield_opt->description =
	_("Relevant only with -t flag");
    tucfield_opt->guisection = _("Turntable");

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

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

    Vect_check_input_output_name(map->answer, output->answer, G_FATAL_EXIT);

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

    type = Vect_option_to_types(type_opt);

    catlist = Vect_new_cat_list();
    Vect_str_to_cat_list(term_opt->answer, catlist);

    /* Iso costs */
    aiso = 1;
    iso = (double *)G_malloc(aiso * sizeof(double));
    /* Set first iso to 0 */
    iso[0] = 0;
    niso = 1;
    i = 0;
    while (cost_opt->answers[i]) {
	if (niso == aiso) {
	    aiso += 1;
	    iso = (double *)G_realloc(iso, aiso * sizeof(double));
	}
	iso[niso] = atof(cost_opt->answers[i]);
	if (iso[niso] <= 0)
	    G_fatal_error(_("Wrong iso cost: %f"), iso[niso]);

	if (iso[niso] <= iso[niso - 1])
	    G_fatal_error(_("Iso cost: %f less than previous"), iso[niso]);

	G_verbose_message(_("Iso cost %d: %f"), niso, iso[niso]);
	niso++;
	i++;
    }

    /* Should not happen: */
    if (niso < 2)
	G_warning(_
		  ("Not enough costs, everything reachable falls to first band"));

    if (geo_f->answer)
	geo = 1;
    else
	geo = 0;

    Vect_set_open_level(2);
    if (Vect_open_old(&Map, map->answer, "") < 0)
	G_fatal_error(_("Unable to open vector map <%s>"), map->answer);

    afield = Vect_get_field_number(&Map, afield_opt->answer);
    nfield = Vect_get_field_number(&Map, nfield_opt->answer);
    tfield = Vect_get_field_number(&Map, tfield_opt->answer);
    tucfield = Vect_get_field_number(&Map, tucfield_opt->answer);

    /* Build graph */
    if (turntable_f->answer)
	Vect_net_ttb_build_graph(&Map, type, afield, nfield, tfield, tucfield,
				 afcol->answer, abcol->answer, ncol->answer,
				 geo, 0);
    else
	Vect_net_build_graph(&Map, type, afield, nfield, afcol->answer,
			     abcol->answer, ncol->answer, geo, 0);

    nnodes = Vect_get_num_nodes(&Map);
    nlines = Vect_get_num_lines(&Map);

    /* Create list of centres based on list of categories */
    for (i = 1; i <= nlines; i++) {
	ltype = Vect_get_line_type(&Map, i);
	if (!(ltype & GV_POINT))
	    continue;

	Vect_read_line(&Map, Points, Cats, i);
	node =
	    Vect_find_node(&Map, Points->x[0], Points->y[0], Points->z[0], 0,
			   0);
	if (!node) {
	    G_warning(_("Point is not connected to the network"));
	    continue;
	}
	if (!(Vect_cat_get(Cats, nfield, &cat)))
	    continue;
	if (Vect_cat_in_cat_list(cat, catlist)) {
	    Vect_net_get_node_cost(&Map, node, &n1cost);
	    if (n1cost == -1) {	/* closed */
		G_warning(_("Centre at closed node (costs = -1) ignored"));
	    }
	    else {
		if (acentres == ncentres) {
		    acentres += 1;
		    Centers =
			(CENTER *) G_realloc(Centers,
					     acentres * sizeof(CENTER));
		}
		Centers[ncentres].cat = cat;
		Centers[ncentres].node = node;
		G_debug(2, "centre = %d node = %d cat = %d", ncentres,
			node, cat);
		ncentres++;
	    }
	}
    }

    G_message(_("Number of centres: %d (nlayer %d)"), ncentres, nfield);

    if (ncentres == 0)
	G_warning(_
		  ("Not enough centres for selected nlayer. Nothing will be allocated."));

    /* alloc and reset space for all nodes */
    if (turntable_f->answer) {
	/* if turntable is used we are looking for lines as destinations, instead of the intersections (nodes) */
	Nodes = (NODE *) G_calloc((nlines * 2 + 2), sizeof(NODE));
	for (i = 2; i <= (nlines * 2 + 2); i++) {
	    Nodes[i].centre = -1;/* NOTE: first two items of Nodes are not used */
	}

    }
    else {
	Nodes = (NODE *) G_calloc((nnodes + 1), sizeof(NODE));
	for (i = 1; i <= nnodes; i++) {
	    Nodes[i].centre = -1;
	}
    }

    apnts1 = 1;
    pnts1 = (ISOPOINT *) G_malloc(apnts1 * sizeof(ISOPOINT));

    apnts2 = 1;
    pnts2 = (ISOPOINT *) G_malloc(apnts2 * sizeof(ISOPOINT));

    /* Fill Nodes by neares centre and costs from that centre */
    for (centre = 0; centre < ncentres; centre++) {
	node1 = Centers[centre].node;
	Vect_net_get_node_cost(&Map, node1, &n1cost);
	G_debug(2, "centre = %d node = %d cat = %d", centre, node1,
		Centers[centre].cat);
	G_message(_("Calculating costs from centre %d..."), centre + 1);
	if (turntable_f->answer)
	    for (line = 1; line <= nlines; line++) {
		G_debug(5, "  node1 = %d line = %d", node1, line);
		Vect_net_get_node_cost(&Map, line, &n2cost);
		/* closed, left it as not attached */

		if (Vect_read_line(&Map, Points, Cats, line) < 0)
		    continue;
		if (Vect_get_line_type(&Map, line) != GV_LINE)
		    continue;
		if (!Vect_cat_get(Cats, tucfield, &cat))
		    continue;

		for (j = 0; j < 2; j++) {
		    if (j == 1)
			cat *= -1;

		    ret =
			Vect_net_ttb_shortest_path(&Map, node1, 0, cat, 1,
						   tucfield, NULL,
						   &cost);
		    if (ret == -1) {
			continue;
		    }		/* node unreachable */

		    /* We must add centre node costs (not calculated by Vect_net_shortest_path() ), but
	             *  only if centre and node are not identical, because at the end node cost is add later */
		    if (ret != 1)
			cost += n1cost;

		    G_debug(5,
			    "Arc nodes: %d %d cost: %f (x old cent: %d old cost %f",
			    node1, line, cost, Nodes[line * 2 + j].centre,
			    Nodes[line * 2 + j].cost);
		    if (Nodes[line * 2 + j].centre == -1 ||
			cost < Nodes[line * 2 + j].cost) {
			Nodes[line * 2 + j].cost = cost;
			Nodes[line * 2 + j].centre = centre;
		    }
		}
	    }
	else
	    for (node2 = 1; node2 <= nnodes; node2++) {
		G_percent(node2, nnodes, 1);
		G_debug(5, "  node1 = %d node2 = %d", node1, node2);
		Vect_net_get_node_cost(&Map, node2, &n2cost);
		if (n2cost == -1) {
		    continue;
		}		/* closed, left it as not attached */

		ret = Vect_net_shortest_path(&Map, node1, node2, NULL, &cost);
		if (ret == -1) {
		    continue;
		}		/* node unreachable */

		/* We must add centre node costs (not calculated by Vect_net_shortest_path() ), but
		 *  only if centre and node are not identical, because at the end node cost is add later */
		if (node1 != node2)
		    cost += n1cost;
		G_debug(5,
			"Arc nodes: %d %d cost: %f (x old cent: %d old cost %f",
			node1, node2, cost, Nodes[node2].centre,
			Nodes[node2].cost);
		if (Nodes[node2].centre == -1 || cost < Nodes[node2].cost) {
		    Nodes[node2].cost = cost;
		    Nodes[node2].centre = centre;
		}
	    }
    }

    /* Write arcs to new map */
    if (Vect_open_new(&Out, output->answer, Vect_is_3d(&Map)) < 0)
	G_fatal_error(_("Unable to create vector map <%s>"), output->answer);

    Vect_hist_command(&Out);

    G_message("Generating isolines...");
    nlines = Vect_get_num_lines(&Map);
    for (line = 1; line <= nlines; line++) {
	G_percent(line, nlines, 2);

	ltype = Vect_read_line(&Map, Points, NULL, line);
	if (!(ltype & type)) {
	    continue;
	}

	l = Vect_line_length(Points);
	if (l == 0)
	    continue;

	if (turntable_f->answer) {
	    centre1 = Nodes[line * 2].centre;
	    centre2 = Nodes[line * 2 + 1].centre;
	    s1cost = Nodes[line * 2].cost;
	    s2cost = Nodes[line * 2 + 1].cost;
	    n1cost = n2cost = 0;
	}
	else {
	    Vect_get_line_nodes(&Map, line, &node1, &node2);
	    centre1 = Nodes[node1].centre;
	    centre2 = Nodes[node2].centre;
	    s1cost = Nodes[node1].cost;
	    s2cost = Nodes[node2].cost;

	    Vect_net_get_node_cost(&Map, node1, &n1cost);
	    Vect_net_get_node_cost(&Map, node2, &n2cost);

	}

	Vect_net_get_line_cost(&Map, line, GV_FORWARD, &e1cost);
	Vect_net_get_line_cost(&Map, line, GV_BACKWARD, &e2cost);

	G_debug(3, "Line %d : length = %f", line, l);
	G_debug(3, "Arc centres: %d %d (nodes: %d %d)", centre1, centre2,
		node1, node2);

	G_debug(3, "  s1cost = %f n1cost = %f e1cost = %f", s1cost, n1cost,
		e1cost);
	G_debug(3, "  s2cost = %f n2cost = %f e2cost = %f", s2cost, n2cost,
		e2cost);


	/* First check if arc is reachable from at least one side */
	if ((centre1 != -1 && n1cost != -1 && e1cost != -1) ||
	    (centre2 != -1 && n2cost != -1 && e2cost != -1)) {
	    /* Line is reachable at least from one side */
	    G_debug(3, "  -> arc is reachable");

	    /* Add costs of node to starting costs */
	    s1cost += n1cost;
	    s2cost += n2cost;

	    e1cost /= l;
	    e2cost /= l;

	    /* Find points on isolines along the line in both directions, add them to array,
	     *  first point is placed at the beginning/end of line */
	    /* Forward */
	    npnts1 = 0;		/* in case this direction is closed */
	    if (centre1 != -1 && n1cost != -1 && e1cost != -1) {
		/* Find iso for beginning of the line */
		next_iso = 0;
		for (i = niso - 1; i >= 0; i--) {
		    if (iso[i] <= s1cost) {
			next_iso = i;
			break;
		    }
		}
		/* Add first */
		pnts1[0].iso = next_iso;
		pnts1[0].distance = 0;
		npnts1++;
		next_iso++;

		/* Calculate distances for points along line */
		while (next_iso < niso) {
		    if (e1cost == 0)
			break;	/* Outside line */
		    l1 = (iso[next_iso] - s1cost) / e1cost;
		    if (l1 >= l)
			break;	/* Outside line */

		    if (npnts1 == apnts1) {
			apnts1 += 1;
			pnts1 =
			    (ISOPOINT *) G_realloc(pnts1,
						   apnts1 * sizeof(ISOPOINT));
		    }
		    pnts1[npnts1].iso = next_iso;
		    pnts1[npnts1].distance = l1;
		    G_debug(3,
			    "  forward %d : iso %d : distance %f : cost %f",
			    npnts1, next_iso, l1, iso[next_iso]);
		    npnts1++;
		    next_iso++;
		}
	    }
	    G_debug(3, "  npnts1 = %d", npnts1);

	    /* Backward */
	    npnts2 = 0;
	    if (centre2 != -1 && n2cost != -1 && e2cost != -1) {
		/* Find iso for beginning of the line */
		next_iso = 0;
		for (i = niso - 1; i >= 0; i--) {
		    if (iso[i] <= s2cost) {
			next_iso = i;
			break;
		    }
		}
		/* Add first */
		pnts2[0].iso = next_iso;
		pnts2[0].distance = l;
		npnts2++;
		next_iso++;

		/* Calculate distances for points along line */
		while (next_iso < niso) {
		    if (e2cost == 0)
			break;	/* Outside line */
		    l1 = (iso[next_iso] - s2cost) / e2cost;
		    if (l1 >= l)
			break;	/* Outside line */

		    if (npnts2 == apnts2) {
			apnts2 += 1;
			pnts2 =
			    (ISOPOINT *) G_realloc(pnts2,
						   apnts2 * sizeof(ISOPOINT));
		    }
		    pnts2[npnts2].iso = next_iso;
		    pnts2[npnts2].distance = l - l1;
		    G_debug(3,
			    "  backward %d : iso %d : distance %f : cost %f",
			    npnts2, next_iso, l - l1, iso[next_iso]);
		    npnts2++;
		    next_iso++;
		}
	    }
	    G_debug(3, "  npnts2 = %d", npnts2);

	    /* Limit number of points by maximum costs in reverse direction, this may remove
	     *  also the first point in one direction, but not in both */
	    /* Forward */
	    if (npnts2 > 0) {
		for (i = 0; i < npnts1; i++) {
		    G_debug(3,
			    "  pnt1 = %d dist1 = %f iso1 = %d max iso2 = %d",
			    i, pnts1[i].distance, pnts1[i].iso,
			    pnts2[npnts2 - 1].iso);
		    if (pnts2[npnts2 - 1].iso < pnts1[i].iso) {
			G_debug(3, "    -> cut here");
			npnts1 = i;
			break;
		    }
		}
	    }
	    G_debug(3, "  npnts1 cut = %d", npnts1);

	    /* Backward */
	    if (npnts1 > 0) {
		for (i = 0; i < npnts2; i++) {
		    G_debug(3,
			    "  pnt2 = %d dist2 = %f iso2 = %d max iso1 = %d",
			    i, pnts2[i].distance, pnts2[i].iso,
			    pnts1[npnts1 - 1].iso);
		    if (pnts1[npnts1 - 1].iso < pnts2[i].iso) {
			G_debug(3, "    -> cut here");
			npnts2 = i;
			break;
		    }
		}
	    }
	    G_debug(3, "  npnts2 cut = %d", npnts2);

	    /* Biggest cost shoud be equal if exist (npnts > 0). Cut out overlapping segments,
	     *  this can cut only points on line but not first points */
	    if (npnts1 > 1 && npnts2 > 1) {
		while (npnts1 > 1 && npnts2 > 1) {
		    if (pnts1[npnts1 - 1].distance >= pnts2[npnts2 - 1].distance) {	/* overlap */
			npnts1--;
			npnts2--;
		    }
		    else {
			break;
		    }
		}
	    }
	    G_debug(3, "  npnts1 2. cut = %d", npnts1);
	    G_debug(3, "  npnts2 2. cut = %d", npnts2);

	    /* Now we have points in both directions which may not overlap, npoints in one
	     *  direction may be 0 but not both */

	    /* Join both arrays, iso of point is for next segment (point is at the beginning) */
	    /* In case npnts1 == 0 add point at distance 0 */
	    if (npnts1 == 0) {
		G_debug(3,
			"  npnts1 = 0 -> add first at distance 0, cat = %d",
			pnts2[npnts2 - 1].iso);
		pnts1[0].iso = pnts2[npnts2 - 1].iso;	/* use last point iso in reverse direction */
		pnts1[0].distance = 0;
		npnts1++;
	    }
	    for (i = npnts2 - 1; i >= 0; i--) {
		/* Check if identical */
		if (pnts1[npnts1 - 1].distance == pnts2[i].distance)
		    continue;

		if (npnts1 == apnts1) {
		    apnts1 += 1;
		    pnts1 =
			(ISOPOINT *) G_realloc(pnts1,
					       apnts1 * sizeof(ISOPOINT));
		}
		pnts1[npnts1].iso = pnts2[i].iso - 1;	/* last may be -1, but it is not used */
		pnts1[npnts1].distance = pnts2[i].distance;
		npnts1++;
	    }
	    /* In case npnts2 == 0 add point at the end */
	    if (npnts2 == 0) {
		pnts1[npnts1].iso = 0;	/* not used */
		pnts1[npnts1].distance = l;
		npnts1++;
	    }

	    /* Create line segments. */
	    for (i = 1; i < npnts1; i++) {
		cat = pnts1[i - 1].iso + 1;
		G_debug(3, "  segment %f - %f cat %d", pnts1[i - 1].distance,
			pnts1[i].distance, cat);
		ret =
		    Vect_line_segment(Points, pnts1[i - 1].distance,
				      pnts1[i].distance, SPoints);
		if (ret == 0) {
		    G_warning(_
			      ("Cannot get line segment, segment out of line"));
		}
		else {
		    Vect_reset_cats(Cats);
		    Vect_cat_set(Cats, 1, cat);
		    Vect_write_line(&Out, ltype, SPoints, Cats);
		}
	    }
	}
	else {
	    /* arc is not reachable */
	    G_debug(3, "  -> arc is not reachable");
	    Vect_reset_cats(Cats);
	    Vect_write_line(&Out, ltype, Points, Cats);
	}
    }

    Vect_build(&Out);

    /* Free, ... */
    G_free(Nodes);
    G_free(Centers);
    Vect_close(&Map);
    Vect_close(&Out);

    exit(EXIT_SUCCESS);
}
コード例 #17
0
ファイル: report.c プロジェクト: rashadkm/grass_cmake
int report(struct Map_info *In, int afield, int nfield, int action)
{
    int i, j, line, nlines, ltype, node, nnodes;
    int cat_line, cat_node[2];

    struct line_cats *Cats, *Cats2;
    struct line_pnts *Points;
    struct bound_box box;

    double x, y, z;

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

    nlines = Vect_get_num_lines(In);

    if (action == TOOL_REPORT) {
	struct boxlist *List;

	List = Vect_new_boxlist(0);

	/* For all lines find categories for points on nodes */
	for (i = 1; i <= nlines; i++) {
	    ltype = Vect_read_line(In, NULL, Cats, i);
	    if (!(ltype & GV_LINES))
		continue;

	    cat_line = 0;
	    if (!Vect_cat_get(Cats, afield, &cat_line))
		G_warning(_("Line %d has no category"), i);

	    cat_node[0] = cat_node[1] = -1;
	    for (j = 0; j < 2; j++) {
		if (j == 0)
		    Vect_get_line_nodes(In, i, &node, NULL);
		else
		    Vect_get_line_nodes(In, i, NULL, &node);

		Vect_get_node_coor(In, node, &x, &y, &z);

		box.E = box.W = x;
		box.N = box.S = y;
		box.T = box.B = z;
		Vect_select_lines_by_box(In, &box, GV_POINT, List);
		
		nnodes = List->n_values;
		if (nnodes > 0) {
		    line = List->id[nnodes - 1]; /* last in list */
		    Vect_read_line(In, NULL, Cats, line);
		    Vect_cat_get(Cats, nfield, &(cat_node[j]));
		}

		if (nnodes == 0) {
		    /* this is ok, not every node needs to be 
		     * represented by a point */
		    G_debug(4, "No point here: %g %g %.g line category: %d",
			      x, y, z, cat_line);
		}
		else if (nnodes > 1)
		    G_warning(_("%d points found: %g %g %g line category: %d"),
			      nnodes, x, y, z, cat_line);
	    }
	    fprintf(stdout, "%d %d %d\n", cat_line, cat_node[0], cat_node[1]);
	}
    }
    else {			/* node report */
	int elem, nelem, type, k, l;
	struct ilist *List;

	List = Vect_new_list();


	for (i = 1; i <= nlines; i++) {
	    
	    if (Vect_get_line_type(In, i) != GV_POINT)
		continue;

	    Vect_read_line(In, Points, Cats, i);

	    box.E = box.W = Points->x[0];
	    box.N = box.S = Points->y[0];
	    box.T = box.B = Points->z[0];
	    
	    nnodes = Vect_select_nodes_by_box(In, &box, List);
	    
	    if (nnodes > 1) {
		G_warning(_("Duplicate nodes at x=%g y=%g z=%g "),
			  Points->x[0], Points->y[0], Points->z[0]);
	    }
	    if (nnodes > 0) {
		node = List->value[0];
		nelem = Vect_get_node_n_lines(In, node);

		/* Loop through all cats of point */
		for (j = 0; j < Cats->n_cats; j++) {
		    if (Cats->field[j] == nfield) {
			int count = 0;

			fprintf(stdout, "%d ", Cats->cat[j]);

			/* Loop through all lines */
			for (k = 0; k < nelem; k++) {
			    elem = abs(Vect_get_node_line(In, node, k));
			    type = Vect_read_line(In, NULL, Cats2, elem);
			    if (!(type & GV_LINES))
				continue;

			    /* Loop through all cats of line */
			    for (l = 0; l < Cats2->n_cats; l++) {
				if (Cats2->field[l] == afield) {
				    if (count > 0)
					fprintf(stdout, ",");

				    fprintf(stdout, "%d", Cats2->cat[l]);
				    count++;
				}
			    }
			}
			fprintf(stdout, "\n");
		    }
		}
	    }
	}
    }

    return 0;
}
コード例 #18
0
ファイル: user1.c プロジェクト: rashadkm/grass_cmake
int INPUT(struct Map_info *In, char *column, char *scol, char *wheresql)
{
    struct quadruple *point;
    double x, y, z, w, nz = 0., sm;
    double c1, c2, c3, c4, c5, c6, nsg;
    int i, j, k = 0, a, irev, cfmask;
    int ddisk = 0;
    double deltx, delty, deltz;
    int first_time = 1;
    CELL *cellmask;
    const char *mapsetm;
    char buf[500];
    int cat, intval;
    struct field_info *Fi;
    dbDriver *Driver;
    dbCatValArray cvarr, sarray;
    int nrec, nrec1, ctype, sctype;
    struct line_pnts *Points;
    struct line_cats *Cats;

    OUTRANGE = 0;
    NPOINT = 0;
    dmin = dmin * dmin;

    /* Read attributes */
    db_CatValArray_init(&cvarr);
    if (scol != NULL)
	db_CatValArray_init(&sarray);
    Fi = Vect_get_field(In, 1);
    if (Fi == NULL)
	G_fatal_error(_("Unable to get layer info for vector map"));

    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);

    nrec =
	db_select_CatValArray(Driver, Fi->table, Fi->key, column, wheresql,
			      &cvarr);
    ctype = cvarr.ctype;
    G_debug(3, "nrec = %d", nrec);

    if (ctype != DB_C_TYPE_INT && ctype != DB_C_TYPE_DOUBLE)
	G_fatal_error(_("Column type of wcolumn is not supported (must be integer or double)"));

    if (nrec < 0)
	G_fatal_error(_("Unable to select data from table"));
    G_message("%d records selected from table", nrec);

    if (scol != NULL) {

	nrec1 =
	    db_select_CatValArray(Driver, Fi->table, Fi->key, scol, wheresql,
				  &sarray);
	sctype = cvarr.ctype;

	if (sctype == -1)
	    G_fatal_error(_("Cannot read column type of smooth column"));
	if (sctype == DB_C_TYPE_DATETIME)
	    G_fatal_error
		(_("Column type of smooth column (datetime) is not supported"));
	if (sctype != DB_C_TYPE_INT && sctype != DB_C_TYPE_DOUBLE)
	    G_fatal_error(_("Column type of smooth column is not supported (must be integer or double)"));
    }

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

    Vect_rewind(In);

    while (1) {
	int ival, type, ret;

	if (-1 == (type = Vect_read_next_line(In, Points, Cats)))
	    G_fatal_error(_("Unable to read vector map"));

	if (type == -2)
	    break;		/* EOF */

	if (!(type & GV_POINTS))
	    continue;

	Vect_cat_get(Cats, 1, &cat);
	if (cat < 0) {
	    G_warning(_("Point without category"));
	    continue;
	}

	x = Points->x[0];
	y = Points->y[0];
	z = Points->z[0];

	if (ctype == DB_C_TYPE_INT) {
	    ret = db_CatValArray_get_value_int(&cvarr, cat, &ival);
	    w = ival;
	}
	else {			/* DB_C_TYPE_DOUBLE */
	    ret = db_CatValArray_get_value_double(&cvarr, cat, &w);
	}

	if (ret != DB_OK) {
	    if (wheresql != NULL)
		/* G_message(_("Database record for cat %d not used due to SQL statement")); */
		/* do nothing in this case to not confuse user. Or implement second cat list */
		;
	    else
		G_warning(_("No record for category %d in table <%s>"), cat,
			  Fi->table);
	    continue;
	}

	if (rsm == -1 && scol != NULL) {

	    if (sctype == DB_C_TYPE_INT) {
		ret = db_CatValArray_get_value_int(&sarray, cat, &intval);
		sm = intval;
	    }
	    else {		/* DB_C_TYPE_DOUBLE */
		ret = db_CatValArray_get_value_double(&sarray, cat, &sm);
	    }
	}


	G_debug(3, "%f %f %f %f", x, y, z, w);

	k++;
	w = w * wmult;
	z = z * zmult;
	c1 = x - ((struct octdata *)(root->data))->x_orig;
	c2 = ((struct octdata *)(root->data))->x_orig +
	    ((struct octdata *)(root->data))->n_cols * ew_res - x;
	c3 = y - ((struct octdata *)(root->data))->y_orig;
	c4 = ((struct octdata *)(root->data))->y_orig +
	    ((struct octdata *)(root->data))->n_rows * ns_res - y;
	c5 = z - ((struct octdata *)(root->data))->z_orig;
	c6 = ((struct octdata *)(root->data))->z_orig +
	    ((struct octdata *)(root->data))->n_levs * tb_res - z;

	if (!
	    ((c1 >= 0) && (c2 >= 0) && (c3 >= 0) && (c4 >= 0) && (c5 >= 0) &&
	     (c6 >= 0))) {
	    if (!OUTRANGE) {
		G_warning(_("Some points outside of region -- will ignore..."));
	    }
	    OUTRANGE++;
	}
	else {
	    if (!(point = point_new(x, y, z, w, sm))) {
		clean();
		G_fatal_error(_("Cannot allocate memory for point"));
	    }

	    a = OT_insert_oct(point, root);
	    if (a == 0) {
		NPOINT++;
	    }
	    if (a < 0) {
		G_warning(_("Can't insert %lf,%lf,%lf,%lf,%lf a=%d"), x, y, z,
			  w, sm, a);
		return -1;
	    }

	    if (first_time) {
		first_time = 0;
		xmin = x;
		ymin = y;
		zmin = z;
		wmin = w;
		xmax = x;
		ymax = y;
		zmax = z;
		wmax = w;
	    }

	    xmin = amin1(xmin, x);
	    ymin = amin1(ymin, y);
	    zmin = amin1(zmin, z);
	    wmin = amin1(wmin, w);
	    xmax = amax1(xmax, x);
	    ymax = amax1(ymax, y);
	    zmax = amax1(zmax, z);
	    wmax = amax1(wmax, w);
	}
    }				/* while */

    db_CatValArray_free(&cvarr);

    c1 = xmin - ((struct octdata *)(root->data))->x_orig;
    c2 = ((struct octdata *)(root->data))->x_orig +
	((struct octdata *)(root->data))->n_cols * ew_res - xmax;
    c3 = ymin - ((struct octdata *)(root->data))->y_orig;
    c4 = ((struct octdata *)(root->data))->y_orig +
	((struct octdata *)(root->data))->n_rows * ns_res - ymax;
    c5 = zmin - ((struct octdata *)(root->data))->z_orig;
    c6 = ((struct octdata *)(root->data))->z_orig +
	((struct octdata *)(root->data))->n_levs * tb_res - zmax;

    if ((c1 > 5 * ew_res) || (c2 > 5 * ew_res) ||
	(c3 > 5 * ns_res) || (c4 > 5 * ns_res) ||
	(c5 > 5 * tb_res) || (c6 > 5 * tb_res)) {
	static int once = 0;

	if (!once) {
	    once = 1;
	    G_warning(_("Strip exists with insufficient data"));
	}
    }

    nz = wmin;
    totsegm = translate_oct(root, ((struct octdata *)(root->data))->x_orig,
			    ((struct octdata *)(root->data))->y_orig,
			    ((struct octdata *)(root->data))->z_orig, nz);
    if (!totsegm) {
	clean();
	G_fatal_error(_("Zero segments!"));
    }

    ((struct octdata *)(root->data))->x_orig = 0;
    ((struct octdata *)(root->data))->y_orig = 0;
    ((struct octdata *)(root->data))->z_orig = 0;	/* was commented out */

    if (outz != NULL)
	ddisk += disk;
    if (gradient != NULL)
	ddisk += disk;
    if (aspect1 != NULL)
	ddisk += disk;
    if (ncurv != NULL)
	ddisk += disk;
    if (gcurv != NULL)
	ddisk += disk;
    if (mcurv != NULL)
	ddisk += disk;

    G_message
	("Processing all selected output files will require %d bytes of disk space for temp files",
	 ddisk);

    /*
       fprintf(stderr,"xmin=%lf,xmax=%lf,ymin=%lf,ymax=%lf,zmin=%lf,zmax=%lf,wmin=%lf,wmax=%lf\n",xmin,xmax,ymin,ymax,zmin,zmax,wmin,wmax);
     */

    fprintf(stderr, "\n");
    if (OUTRANGE > 0)
	G_warning
	    (_("There are points outside specified 2D/3D region--ignored %d points (total points: %d)"),
	     OUTRANGE, k);
    if (NPOINT > 0)
	G_warning
	    (_("Points are more dense than specified 'DMIN'--ignored %d points (remain %d)"),
	     NPOINT, k - NPOINT);
    NPOINT = k - NPOINT - NPT - OUTRANGE;
    if (NPOINT < KMIN) {
	if (NPOINT != 0) {
	    G_warning
		(_("%d points given for interpolation (after thinning) is less than given NPMIN=%d"),
		 NPOINT, KMIN);
	    KMIN = NPOINT;
	}
	else {
	    fprintf(stderr, "ERROR: zero points in the given region!\n");
	    return -1;
	}
    }
    if (NPOINT > KMAXPOINTS && KMIN <= KMAX) {
	fprintf(stderr,
		"ERROR: segmentation parameters set to invalid values: npmin = %d, segmax = %d \n",
		KMIN, KMAX);
	fprintf(stderr,
		"for smooth connection of segments, npmin > segmax (see manual) \n");
	return -1;
    }

    if (NPOINT < KMAXPOINTS && KMAX != KMAXPOINTS)
	G_warning
	    (_("There is less than %d points for interpolation, no segmentation is necessary, to run the program faster, set segmax=%d (see manual)"),
	     KMAXPOINTS, KMAXPOINTS);

    deltx = xmax - xmin;
    delty = ymax - ymin;
    deltz = zmax - zmin;
    nsg = (double)NPOINT / (double)KMIN;
    dnorm = deltx * delty * deltz / nsg;
    nsg = 3.0;
    nsg = 1. / nsg;
    dnorm = pow(dnorm, nsg);
    /* DEBUG
       if (fd4 != NULL)
       fprintf (fd4, "deltx,delty %f %f \n", deltx, delty);
     */
    nsizc = current_region.cols;	/* ((int)(deltx/ew_res))+1;  */
    nsizr = current_region.rows;	/* ((int)(delty/ns_res))+1;   */
    NPT = k;
    x0utm = 0.;
    y0utm = 0.;
    z0utm = 0.;

  /** create a bitmap mask from given raster map **/
    if (maskmap != NULL) {
	mapsetm = G_find_raster2(maskmap, "");
	if (!mapsetm) {
	    clean();
	    G_fatal_error(_("Mask raster map [%s] not found"), maskmap);
	}
	bitmask = BM_create(nsizc, nsizr);
	cellmask = Rast_allocate_c_buf();
	cfmask = Rast_open_old(maskmap, mapsetm);
	for (i = 0; i < nsizr; i++) {
	    irev = nsizr - i - 1;
	    Rast_get_c_row(cfmask, cellmask, i);
	    for (j = 0; j < nsizc; j++) {
		if ((cellmask[j] == 0) || Rast_is_c_null_value(&cellmask[j]))
		    BM_set(bitmask, j, irev, 0);
		else
		    BM_set(bitmask, j, irev, 1);
	    }
	}
	G_message(_("Bitmap mask created"));
    }

    return 1;
}
コード例 #19
0
ファイル: main.c プロジェクト: AsherBond/MondocosmOS
int main(int argc, char *argv[])
{
    struct Map_info In, Out, Buf;
    struct line_pnts *Points;
    struct line_cats *Cats, *BCats;
    char bufname[GNAME_MAX];
    struct GModule *module;
    struct Option *in_opt, *out_opt, *type_opt, *dista_opt, *distb_opt,
	*angle_opt;
    struct Flag *straight_flag, *nocaps_flag;
    struct Option *tol_opt, *bufcol_opt, *scale_opt, *field_opt;

    int verbose;
    double da, db, dalpha, tolerance, unit_tolerance;
    int type;
    int i, ret, nareas, area, nlines, line;
    char *Areas, *Lines;
    int field;
    struct buf_contours *arr_bc;
    struct buf_contours_pts arr_bc_pts;
    int buffers_count = 0, line_id;
    struct spatial_index si;
    struct bound_box bbox;

    /* Attributes if sizecol is used */
    int nrec, ctype;
    struct field_info *Fi;
    dbDriver *Driver;
    dbCatValArray cvarr;
    double size_val, scale;


    module = G_define_module();
    G_add_keyword(_("vector"));
    G_add_keyword(_("geometry"));
    G_add_keyword(_("buffer"));
    module->description =
	_("Creates a buffer around vector features of given type.");

    in_opt = G_define_standard_option(G_OPT_V_INPUT);

    field_opt = G_define_standard_option(G_OPT_V_FIELD_ALL);
    field_opt->guisection = _("Selection");

    type_opt = G_define_standard_option(G_OPT_V_TYPE);
    type_opt->options = "point,line,boundary,centroid,area";
    type_opt->answer = "point,line,area";
    type_opt->guisection = _("Selection");

    out_opt = G_define_standard_option(G_OPT_V_OUTPUT);
    
    dista_opt = G_define_option();
    dista_opt->key = "distance";
    dista_opt->type = TYPE_DOUBLE;
    dista_opt->required = NO;
    dista_opt->description =
	_("Buffer distance along major axis in map units");
    dista_opt->guisection = _("Distance");

    distb_opt = G_define_option();
    distb_opt->key = "minordistance";
    distb_opt->type = TYPE_DOUBLE;
    distb_opt->required = NO;
    distb_opt->description =
	_("Buffer distance along minor axis in map units");
    distb_opt->guisection = _("Distance");

    angle_opt = G_define_option();
    angle_opt->key = "angle";
    angle_opt->type = TYPE_DOUBLE;
    angle_opt->required = NO;
    angle_opt->answer = "0";
    angle_opt->description = _("Angle of major axis in degrees");
    angle_opt->guisection = _("Distance");

    bufcol_opt = G_define_standard_option(G_OPT_DB_COLUMN);
    bufcol_opt->key = "bufcolumn";
    bufcol_opt->description =
	_("Name of column to use for buffer distances");
    bufcol_opt->guisection = _("Distance");

    scale_opt = G_define_option();
    scale_opt->key = "scale";
    scale_opt->type = TYPE_DOUBLE;
    scale_opt->required = NO;
    scale_opt->answer = "1.0";
    scale_opt->description = _("Scaling factor for attribute column values");
    scale_opt->guisection = _("Distance");

    tol_opt = G_define_option();
    tol_opt->key = "tolerance";
    tol_opt->type = TYPE_DOUBLE;
    tol_opt->required = NO;
    tol_opt->answer = "0.01";
    tol_opt->description =
	_("Maximum distance between theoretical arc and polygon segments as multiple of buffer");
    tol_opt->guisection = _("Distance");

    straight_flag = G_define_flag();
    straight_flag->key = 's';
    straight_flag->description = _("Make outside corners straight");

    nocaps_flag = G_define_flag();
    nocaps_flag->key = 'c';
    nocaps_flag->description = _("Don't make caps at the ends of polylines");

    G_gisinit(argv[0]);
    
    if (G_parser(argc, argv))
	exit(EXIT_FAILURE);

    type = Vect_option_to_types(type_opt);

    if ((dista_opt->answer && bufcol_opt->answer) ||
	(!(dista_opt->answer || bufcol_opt->answer)))
	G_fatal_error(_("Select a buffer distance/minordistance/angle "
			"or column, but not both."));

    if (bufcol_opt->answer)
	G_warning(_("The bufcol option may contain bugs during the cleaning "
		    "step. If you encounter problems, use the debug "
		    "option or clean manually with v.clean tool=break; "
		    "v.category step=0; v.extract -d type=area"));

    if (field_opt->answer)
	field = Vect_get_field_number(&In, field_opt->answer);
    else
	field = -1;
	
    if (bufcol_opt->answer && field == -1)
	G_fatal_error(_("The bufcol option requires a valid layer."));

    tolerance = atof(tol_opt->answer);
    if (tolerance <= 0)
	G_fatal_error(_("The tolerance must be > 0."));

    if (adjust_tolerance(&tolerance))
	G_warning(_("The tolerance was reset to %g"), tolerance);

    scale = atof(scale_opt->answer);
    if (scale <= 0.0)
	G_fatal_error("Illegal scale value");

    da = db = dalpha = 0;
    if (dista_opt->answer) {
	da = atof(dista_opt->answer);

	if (distb_opt->answer)
	    db = atof(distb_opt->answer);
	else
	    db = da;

	if (angle_opt->answer)
	    dalpha = atof(angle_opt->answer);
	else
	    dalpha = 0;

	unit_tolerance = tolerance * MIN(da, db);
	G_verbose_message(_("The tolerance in map units = %g"), unit_tolerance);
    }

    Vect_check_input_output_name(in_opt->answer, out_opt->answer,
				 GV_FATAL_EXIT);

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

    Vect_set_open_level(2); /* topology required */

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

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

    /* open tmp vector for buffers, needed for cleaning */
    sprintf(bufname, "%s_tmp_%d", out_opt->answer, getpid());
    if (0 > Vect_open_new(&Buf, bufname, 0)) {
	Vect_close(&In);
	Vect_close(&Out);
	Vect_delete(out_opt->answer);
	exit(EXIT_FAILURE);
    }
    Vect_build_partial(&Buf, GV_BUILD_BASE);

    /* check and load attribute column data */
    if (bufcol_opt->answer) {
	db_CatValArray_init(&cvarr);

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

	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);

	/* Note do not check if the column exists in the table because it may be expression */

	/* TODO: only select values we need instead of all in column */
	nrec =
	    db_select_CatValArray(Driver, Fi->table, Fi->key,
				  bufcol_opt->answer, NULL, &cvarr);
	if (nrec < 0)
	    G_fatal_error(_("Unable to select data from table <%s>"),
			  Fi->table);
	G_debug(2, "%d records selected from table", nrec);

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

	db_close_database_shutdown_driver(Driver);

	/* Output cats/values list */
	for (i = 0; i < cvarr.n_values; i++) {
	    if (ctype == DB_C_TYPE_INT) {
		G_debug(4, "cat = %d val = %d", cvarr.value[i].cat,
			cvarr.value[i].val.i);
	    }
	    else if (ctype == DB_C_TYPE_DOUBLE) {
		G_debug(4, "cat = %d val = %f", cvarr.value[i].cat,
			cvarr.value[i].val.d);
	    }
	}
    }

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


    /* Create buffers' boundaries */
    nlines = nareas = 0;
    if ((type & GV_POINTS) || (type & GV_LINES))
	nlines += Vect_get_num_primitives(&In, type);
    if (type & GV_AREA)
	nareas = Vect_get_num_areas(&In);
    
    if (nlines + nareas == 0) {
	G_warning(_("No features available for buffering. "
	            "Check type option and features available in the input vector."));
	exit(EXIT_SUCCESS);
    }

    buffers_count = 1;
    arr_bc = G_malloc((nlines + nareas + 1) * sizeof(struct buf_contours));

    Vect_spatial_index_init(&si, 0);

    /* Lines (and Points) */
    if ((type & GV_POINTS) || (type & GV_LINES)) {
	int ltype;

	if (nlines > 0)
	    G_message(_("Buffering lines..."));
	for (line = 1; line <= nlines; line++) {
	    int cat;

	    G_debug(2, "line = %d", line);
	    G_percent(line, nlines, 2);
	    
	    if (!Vect_line_alive(&In, line))
		continue;

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

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

	    if (bufcol_opt->answer) {
		ret = db_CatValArray_get_value_di(&cvarr, cat, &size_val);
		if (ret != DB_OK) {
		    G_warning(_("No record for category %d in table <%s>"),
			      cat, Fi->table);
		    continue;
		}

		if (size_val < 0.0) {
		    G_warning(_("Attribute is of invalid size (%.3f) for category %d"),
			      size_val, cat);
		    continue;
		}

		if (size_val == 0.0)
		    continue;

		da = size_val * scale;
		db = da;
		dalpha = 0;
		unit_tolerance = tolerance * MIN(da, db);

		G_debug(2, "    dynamic buffer size = %.2f", da);
		G_debug(2, _("The tolerance in map units: %g"),
			unit_tolerance);
	    }
	    
	    Vect_line_prune(Points);
	    if (ltype & GV_POINTS || Points->n_points == 1) {
		Vect_point_buffer2(Points->x[0], Points->y[0], da, db, dalpha,
				   !(straight_flag->answer), unit_tolerance,
				   &(arr_bc_pts.oPoints));

		Vect_write_line(&Out, GV_BOUNDARY, arr_bc_pts.oPoints, BCats);
		line_id = Vect_write_line(&Buf, GV_BOUNDARY, arr_bc_pts.oPoints, Cats);
		Vect_destroy_line_struct(arr_bc_pts.oPoints);
		/* add buffer to spatial index */
		Vect_get_line_box(&Buf, line_id, &bbox);
		Vect_spatial_index_add_item(&si, buffers_count, &bbox);
		arr_bc[buffers_count].outer = line_id;
		arr_bc[buffers_count].inner_count = 0;
		arr_bc[buffers_count].inner = NULL;
		buffers_count++;

	    }
	    else {
		Vect_line_buffer2(Points, da, db, dalpha,
				  !(straight_flag->answer),
				  !(nocaps_flag->answer), unit_tolerance,
				  &(arr_bc_pts.oPoints),
				  &(arr_bc_pts.iPoints),
				  &(arr_bc_pts.inner_count));

		Vect_write_line(&Out, GV_BOUNDARY, arr_bc_pts.oPoints, BCats);
		line_id = Vect_write_line(&Buf, GV_BOUNDARY, arr_bc_pts.oPoints, Cats);
		Vect_destroy_line_struct(arr_bc_pts.oPoints);
		/* add buffer to spatial index */
		Vect_get_line_box(&Buf, line_id, &bbox);
		Vect_spatial_index_add_item(&si, buffers_count, &bbox);
		arr_bc[buffers_count].outer = line_id;

		arr_bc[buffers_count].inner_count = arr_bc_pts.inner_count;
		if (arr_bc_pts.inner_count > 0) {
		    arr_bc[buffers_count].inner = G_malloc(arr_bc_pts.inner_count * sizeof(int));
		    for (i = 0; i < arr_bc_pts.inner_count; i++) {
			Vect_write_line(&Out, GV_BOUNDARY, arr_bc_pts.iPoints[i], BCats);
			line_id = Vect_write_line(&Buf, GV_BOUNDARY, arr_bc_pts.iPoints[i], Cats);
			Vect_destroy_line_struct(arr_bc_pts.iPoints[i]);
			/* add buffer to spatial index */
			Vect_get_line_box(&Buf, line_id, &bbox);
			Vect_spatial_index_add_item(&si, buffers_count, &bbox);
			arr_bc[buffers_count].inner[i] = line_id;
		    }
		    G_free(arr_bc_pts.iPoints);
		}
		buffers_count++;
	    }
	}
    }

    /* Areas */
    if (type & GV_AREA) {
	int centroid;

	if (nareas > 0) 
	    G_message(_("Buffering areas..."));
	for (area = 1; area <= nareas; area++) {
	    int cat;

	    G_percent(area, nareas, 2);
	    
	    if (!Vect_area_alive(&In, area))
		continue;
	    
	    centroid = Vect_get_area_centroid(&In, area);
	    if (centroid == 0)
		continue;

	    Vect_read_line(&In, NULL, Cats, centroid);
	    if (field > 0 && !Vect_cat_get(Cats, field, &cat))
		continue;

	    if (bufcol_opt->answer) {
		ret = db_CatValArray_get_value_di(&cvarr, cat, &size_val);
		if (ret != DB_OK) {
		    G_warning(_("No record for category %d in table <%s>"),
			      cat, Fi->table);
		    continue;
		}

		if (size_val < 0.0) {
		    G_warning(_("Attribute is of invalid size (%.3f) for category %d"),
			      size_val, cat);
		    continue;
		}

		if (size_val == 0.0)
		    continue;

		da = size_val * scale;
		db = da;
		dalpha = 0;
		unit_tolerance = tolerance * MIN(da, db);

		G_debug(2, "    dynamic buffer size = %.2f", da);
		G_debug(2, _("The tolerance in map units: %g"),
			unit_tolerance);
	    }

	    Vect_area_buffer2(&In, area, da, db, dalpha,
			      !(straight_flag->answer),
			      !(nocaps_flag->answer), unit_tolerance,
			      &(arr_bc_pts.oPoints),
			      &(arr_bc_pts.iPoints),
			      &(arr_bc_pts.inner_count));

	    Vect_write_line(&Out, GV_BOUNDARY, arr_bc_pts.oPoints, BCats);
	    line_id = Vect_write_line(&Buf, GV_BOUNDARY, arr_bc_pts.oPoints, Cats);
	    Vect_destroy_line_struct(arr_bc_pts.oPoints);
	    /* add buffer to spatial index */
	    Vect_get_line_box(&Buf, line_id, &bbox);
	    Vect_spatial_index_add_item(&si, buffers_count, &bbox);
	    arr_bc[buffers_count].outer = line_id;

	    arr_bc[buffers_count].inner_count = arr_bc_pts.inner_count;
	    if (arr_bc_pts.inner_count > 0) {
		arr_bc[buffers_count].inner = G_malloc(arr_bc_pts.inner_count * sizeof(int));
		for (i = 0; i < arr_bc_pts.inner_count; i++) {
		    Vect_write_line(&Out, GV_BOUNDARY, arr_bc_pts.iPoints[i], BCats);
		    line_id = Vect_write_line(&Buf, GV_BOUNDARY, arr_bc_pts.iPoints[i], Cats);
		    Vect_destroy_line_struct(arr_bc_pts.iPoints[i]);
		    /* add buffer to spatial index */
		    Vect_get_line_box(&Buf, line_id, &bbox);
		    Vect_spatial_index_add_item(&si, buffers_count, &bbox);
		    arr_bc[buffers_count].inner[i] = line_id;
		}
		G_free(arr_bc_pts.iPoints);
	    }
	    buffers_count++;
	}
    }

    verbose = G_verbose();

    G_message(_("Cleaning buffers..."));
    
    /* Break lines */
    G_message(_("Building parts of topology..."));
    Vect_build_partial(&Out, GV_BUILD_BASE);

    G_message(_("Snapping boundaries..."));
    Vect_snap_lines(&Out, GV_BOUNDARY, 1e-7, NULL);

    G_message(_("Breaking polygons..."));
    Vect_break_polygons(&Out, GV_BOUNDARY, NULL);

    G_message(_("Removing duplicates..."));
    Vect_remove_duplicates(&Out, GV_BOUNDARY, NULL);

    do {
	G_message(_("Breaking boundaries..."));
	Vect_break_lines(&Out, GV_BOUNDARY, NULL);

	G_message(_("Removing duplicates..."));
	Vect_remove_duplicates(&Out, GV_BOUNDARY, NULL);

	G_message(_("Cleaning boundaries at nodes"));

    } while (Vect_clean_small_angles_at_nodes(&Out, GV_BOUNDARY, NULL) > 0);

    /* Dangles and bridges don't seem to be necessary if snapping is small enough. */
    /* Still needed for larger buffer distances ? */

    /*
    G_message(_("Removing dangles..."));
    Vect_remove_dangles(&Out, GV_BOUNDARY, -1, NULL);

    G_message (_("Removing bridges..."));
    Vect_remove_bridges(&Out, NULL);
    */

    G_message(_("Attaching islands..."));
    Vect_build_partial(&Out, GV_BUILD_ATTACH_ISLES);

    /* Calculate new centroids for all areas */
    nareas = Vect_get_num_areas(&Out);
    Areas = (char *)G_calloc(nareas + 1, sizeof(char));
    G_message(_("Calculating centroids for areas..."));
    G_percent(0, nareas, 2);
    for (area = 1; area <= nareas; area++) {
	double x, y;

	G_percent(area, nareas, 2);

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

	if (!Vect_area_alive(&Out, area))
	    continue;

	ret = Vect_get_point_in_area(&Out, area, &x, &y);
	if (ret < 0) {
	    G_warning(_("Cannot calculate area centroid"));
	    continue;
	}

	ret = point_in_buffer(arr_bc, &si, &Buf, x, y);

	if (ret) {
	    G_debug(3, "  -> in buffer");
	    Areas[area] = 1;
	}
    }

    /* Make a list of boundaries to be deleted (both sides inside) */
    nlines = Vect_get_num_lines(&Out);
    G_debug(3, "nlines = %d", nlines);
    Lines = (char *)G_calloc(nlines + 1, sizeof(char));

    G_message(_("Generating list of boundaries to be deleted..."));
    for (line = 1; line <= nlines; line++) {
	int j, side[2], areas[2];

	G_percent(line, nlines, 2);

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

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

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

	for (j = 0; j < 2; j++) {
	    if (side[j] == 0) {	/* area/isle not build */
		areas[j] = 0;
	    }
	    else if (side[j] > 0) {	/* area */
		areas[j] = side[j];
	    }
	    else {		/* < 0 -> island */
		areas[j] = Vect_get_isle_area(&Out, abs(side[j]));
	    }
	}

	G_debug(3, " areas = %d , %d -> Areas = %d, %d", areas[0], areas[1],
		Areas[areas[0]], Areas[areas[1]]);
	if (Areas[areas[0]] && Areas[areas[1]])
	    Lines[line] = 1;
    }
    G_free(Areas);

    /* Delete boundaries */
    G_message(_("Deleting boundaries..."));
    for (line = 1; line <= nlines; line++) {
	G_percent(line, nlines, 2);
	
	if (!Vect_line_alive(&Out, line))
	    continue;

	if (Lines[line]) {
	    G_debug(3, " delete line %d", line);
	    Vect_delete_line(&Out, line);
	}
	else {
	    /* delete incorrect boundaries */
	    int side[2];

	    Vect_get_line_areas(&Out, line, &side[0], &side[1]);
	    
	    if (!side[0] && !side[1])
		Vect_delete_line(&Out, line);
	}
    }

    G_free(Lines);

    /* Create new centroids */
    Vect_reset_cats(Cats);
    Vect_cat_set(Cats, 1, 1);
    nareas = Vect_get_num_areas(&Out);

    G_message(_("Calculating centroids for areas..."));    
    for (area = 1; area <= nareas; area++) {
	double x, y;

	G_percent(area, nareas, 2);

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

	if (!Vect_area_alive(&Out, area))
	    continue;

	ret = Vect_get_point_in_area(&Out, area, &x, &y);
	if (ret < 0) {
	    G_warning(_("Cannot calculate area centroid"));
	    continue;
	}

	ret = point_in_buffer(arr_bc, &si, &Buf, x, y);

	if (ret) {
	    Vect_reset_line(Points);
	    Vect_append_point(Points, x, y, 0.);
	    Vect_write_line(&Out, GV_CENTROID, Points, Cats);
	}
    }

    /* free arr_bc[] */
    /* will only slow down the module
       for (i = 0; i < buffers_count; i++) {
       Vect_destroy_line_struct(arr_bc[i].oPoints);
       for (j = 0; j < arr_bc[i].inner_count; j++)
       Vect_destroy_line_struct(arr_bc[i].iPoints[j]);
       G_free(arr_bc[i].iPoints);
       } */

    Vect_spatial_index_destroy(&si);
    Vect_close(&Buf);
    Vect_delete(bufname);

    G_set_verbose(verbose);

    Vect_close(&In);

    Vect_build_partial(&Out, GV_BUILD_NONE);
    Vect_build(&Out);
    Vect_close(&Out);

    exit(EXIT_SUCCESS);
}
コード例 #20
0
ファイル: main.c プロジェクト: imincik/pkg-grass
int main(int argc, char *argv[])
{
    struct Map_info In, Out;
    static struct line_pnts *Points;
    struct line_cats *Cats;
    struct GModule *module;	/* GRASS module for parsing arguments */
    struct Option *map_in, *map_out;
    struct Option *cat_opt, *field_opt, *where_opt, *abcol, *afcol;
    struct Option *iter_opt, *error_opt;
    struct Flag *geo_f, *add_f;
    int chcat, with_z;
    int layer, mask_type;
    struct varray *varray;
    dglGraph_s *graph;
    int i, geo, nnodes, nlines, j, max_cat;
    char buf[2000], *covered;

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

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

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

    map_out = G_define_standard_option(G_OPT_V_OUTPUT);

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    Vect_set_open_level(2);

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

    with_z = Vect_is_3d(&In);

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


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

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

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

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

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

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

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

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

    db_begin_transaction(driver);

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

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

    deg = closeness = betw = eigen = NULL;

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

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

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

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

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


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


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

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

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

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

    }

    db_commit_transaction(driver);
    db_close_database_shutdown_driver(driver);

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

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

    exit(EXIT_SUCCESS);
}
コード例 #21
0
ファイル: report.c プロジェクト: imincik/pkg-grass
int report(struct Map_info *In, int afield, int nfield, int action)
{
    int i, j, k, line, ltype, nnodes;
    int cat_line, cat_node[2];
    struct line_cats *Cats, *Cats2;
    int node;
    double x, y, z;

    Cats = Vect_new_cats_struct();
    Cats2 = Vect_new_cats_struct();

    if (action == TOOL_REPORT) {
	/* For all lines find categories for points on nodes */
	for (i = 1; i <= Vect_get_num_lines(In); i++) {
	    ltype = Vect_read_line(In, NULL, Cats, i);
	    if (ltype != GV_LINE)
		continue;

	    cat_line = 0;
	    if (!Vect_cat_get(Cats, afield, &cat_line))
		G_warning(_("Line %d has no category"), i);

	    cat_node[0] = cat_node[1] = 0;
	    for (j = 0; j < 2; j++) {
		if (j == 0)
		    Vect_get_line_nodes(In, i, &node, NULL);
		else
		    Vect_get_line_nodes(In, i, NULL, &node);

		Vect_get_node_coor(In, node, &x, &y, &z);
		nnodes = 0;

		for (k = 0; k < Vect_get_node_n_lines(In, node); k++) {
		    line = abs(Vect_get_node_line(In, node, k));
		    ltype = Vect_read_line(In, NULL, Cats, line);
		    if (ltype != GV_POINT)
			continue;

		    Vect_cat_get(Cats, nfield, &(cat_node[j]));

		    nnodes++;
		}
		if (nnodes == 0)
		    G_warning(_("Point not found: %.3lf %.3lf %.3lf line category: %d"),
			      x, y, z, cat_line);
		else if (nnodes > 1)
		    G_warning(_("%d points found: %.3lf %.3lf %.3lf line category: %d"),
			      nnodes, x, y, z, cat_line);
	    }
	    fprintf(stdout, "%d %d %d\n", cat_line, cat_node[0], cat_node[1]);
	}
    }
    else {			/* node report */

	int nnodes, node;

	nnodes = Vect_get_num_nodes(In);

	for (node = 1; node <= nnodes; node++) {
	    int nelem, elem, type, i, j, k, l;

	    nelem = Vect_get_node_n_lines(In, node);

	    /* Loop through all points */
	    for (i = 0; i < nelem; i++) {
		elem = abs(Vect_get_node_line(In, node, i));
		type = Vect_read_line(In, NULL, Cats, elem);
		if (type != GV_POINT)
		    continue;

		/* Loop through all cats of point */
		for (j = 0; j < Cats->n_cats; j++) {
		    if (Cats->field[j] == nfield) {
			int count = 0;

			fprintf(stdout, "%d ", Cats->cat[j]);

			/* Loop through all lines */
			for (k = 0; k < nelem; k++) {
			    elem = abs(Vect_get_node_line(In, node, k));
			    type = Vect_read_line(In, NULL, Cats2, elem);
			    if (!(type & GV_LINES))
				continue;

			    /* Loop through all cats of line */
			    for (l = 0; l < Cats2->n_cats; l++) {
				if (Cats2->field[l] == afield) {
				    if (count > 0)
					fprintf(stdout, ",");

				    fprintf(stdout, "%d", Cats2->cat[l]);
				    count++;
				}
			    }
			}
			fprintf(stdout, "\n");
		    }
		}
	    }
	}
    }

    return 0;
}
コード例 #22
0
ファイル: main.c プロジェクト: AsherBond/MondocosmOS
int main(int argc, char *argv[])
{
    struct GModule *module;
    struct Option *in_opt, *layer_opt, *out_opt, *length_opt, *units_opt, *vertices_opt;
    
    struct Map_info In, Out;
    struct line_pnts *Points, *Points2;
    struct line_cats *Cats;

    int line, nlines, layer;
    double length = -1;
    int vertices = 0;
    double (*line_length) ();
    int latlon = 0;

    G_gisinit(argv[0]);

    module = G_define_module();
    G_add_keyword(_("vector"));
    G_add_keyword(_("geometry"));
    module->description = _("Splits vector lines to shorter segments.");
    
    in_opt = G_define_standard_option(G_OPT_V_INPUT);

    layer_opt = G_define_standard_option(G_OPT_V_FIELD_ALL);

    out_opt = G_define_standard_option(G_OPT_V_OUTPUT);
    
    length_opt = G_define_option();
    length_opt->key = "length";
    length_opt->type = TYPE_DOUBLE;
    length_opt->required = NO;
    length_opt->multiple = NO;
    length_opt->description = _("Maximum segment length");

    units_opt = G_define_option();
    units_opt->key = "units";
    units_opt->type = TYPE_STRING;
    units_opt->required = NO;
    units_opt->multiple = NO;
    units_opt->options = "meters,kilometers,feet,miles,nautmiles";
    units_opt->answer = "meters";
    units_opt->description = _("Length units");
    
    vertices_opt = G_define_option();
    vertices_opt->key = "vertices";
    vertices_opt->type = TYPE_INTEGER;
    vertices_opt->required = NO;
    vertices_opt->multiple = NO;
    vertices_opt->description = _("Maximum number of vertices in segment");
    
    if (G_parser(argc, argv))
	exit(EXIT_FAILURE);
    
    if ((length_opt->answer && vertices_opt->answer) ||
	!(length_opt->answer || vertices_opt->answer))
	G_fatal_error(_("Use either length or vertices"));

    line_length = NULL;

    if (length_opt->answer) {
	length = atof(length_opt->answer);
	if (length <= 0)
	    G_fatal_error(_("Length must be positive but is %g"), length);

	/* convert length to meters */
	if (strcmp(units_opt->answer, "meters") == 0)
	    /* do nothing */ ;
	else if (strcmp(units_opt->answer, "kilometers") == 0)
	    length *= FROM_KILOMETERS;
	else if (strcmp(units_opt->answer, "feet") == 0)
	    length *= FROM_FEET;
	else if (strcmp(units_opt->answer, "miles") == 0)
	    length *= FROM_MILES;
	else if (strcmp(units_opt->answer, "nautmiles") == 0)
	    length *= FROM_NAUTMILES;
	else
	    G_fatal_error(_("Unknown unit %s"), units_opt->answer); 

	/* set line length function */
	if ((latlon = (G_projection() == PROJECTION_LL)) == 1)
	    line_length = Vect_line_geodesic_length;
	else {
	    double factor;
	    
	    line_length = Vect_line_length;
	    
	    /* convert length to map units */
	    if ((factor = G_database_units_to_meters_factor()) == 0)
		G_fatal_error(_("Can not get projection units"));
	    else {
		/* meters to units */
		length = length / factor;
	    }
	}
	G_verbose_message(_("length in %s: %g"), (latlon ? "meters" : "map units"), length);
    }

    if (vertices_opt->answer) {
	vertices = atoi(vertices_opt->answer);
	if (vertices < 2)
	    G_fatal_error(_("Number of vertices must be at least 2"));
    }
    
    Vect_set_open_level(2);
    Vect_open_old2(&In, in_opt->answer, "", layer_opt->answer);
    layer = Vect_get_field_number(&In, layer_opt->answer);
    
    Vect_open_new(&Out, out_opt->answer, Vect_is_3d(&In));
    
    Vect_copy_head_data(&In, &Out);
    Vect_hist_copy(&In, &Out);
    Vect_hist_command(&Out);
    Vect_copy_tables(&In, &Out, layer);
    
    Points = Vect_new_line_struct();
    Points2 = Vect_new_line_struct();
    Cats = Vect_new_cats_struct();

    nlines = Vect_get_num_lines(&In);

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

	G_percent(line, nlines, 1);

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

	ltype = Vect_read_line(&In, Points, Cats, line);

	if (layer != -1 && !Vect_cat_get(Cats, layer, NULL))
	  continue;

	if (ltype & GV_LINES) {
	    if (length > 0) {
		double l, from, to, step;

		l = line_length(Points);

		if (l <= length) {
		    Vect_write_line(&Out, ltype, Points, Cats);
		}
		else {
		    int n, i;

		    n = ceil(l / length);
		    if (latlon)
			l = Vect_line_length(Points);

		    step = l / n;
		    from = 0.;

		    for (i = 0; i < n; i++) {
			int ret;
			double x, y, z;

			if (i == n - 1) {
			    to = l;	/* to be sure that it goes to end */
			}
			else {
			    to = from + step;
			}

			ret = Vect_line_segment(Points, from, to, Points2);
			if (ret == 0) {
			    G_warning(_("Unable to make line segment: %f - %f (line length = %f)"),
				      from, to, l);
			    continue;
			}

			/* To be sure that the coordinates are identical */
			if (i > 0) {
			    Points2->x[0] = x;
			    Points2->y[0] = y;
			    Points2->z[0] = z;
			}
			if (i == n - 1) {
			    Points2->x[Points2->n_points - 1] =
				Points->x[Points->n_points - 1];
			    Points2->y[Points2->n_points - 1] =
				Points->y[Points->n_points - 1];
			    Points2->z[Points2->n_points - 1] =
				Points->z[Points->n_points - 1];
			}

			Vect_write_line(&Out, ltype, Points2, Cats);

			/* last point */
			x = Points2->x[Points2->n_points - 1];
			y = Points2->y[Points2->n_points - 1];
			z = Points2->z[Points2->n_points - 1];

			from += step;
		    }
		}
	    }
	    else {
		int start = 0;	/* number of coordinates written */

		while (start < Points->n_points - 1) {
		    int i, v;

		    Vect_reset_line(Points2);
		    for (i = 0; i < vertices; i++) {
			v = start + i;
			if (v == Points->n_points)
			    break;

			Vect_append_point(Points2, Points->x[v], Points->y[v],
					  Points->z[v]);
		    }

		    Vect_write_line(&Out, ltype, Points2, Cats);

		    start = v;
		}
	    }
	}
	else {
	    Vect_write_line(&Out, ltype, Points, Cats);
	}
    }

    Vect_close(&In);
    Vect_build(&Out);
    Vect_close(&Out);
    
    exit(EXIT_SUCCESS);
}
コード例 #23
0
ファイル: trans3.c プロジェクト: AsherBond/MondocosmOS
/*!
   \brief transform 3d vector features to 2d (z-coordinate is omitted)

   \param In input vector
   \param Out output vector
   \param type feature type to be transformed
   \param field layer number
   \param zcolumn attribute column where to store height

   \return number of writen features
   \return -1 on error
 */
int trans3d(struct Map_info *In, struct Map_info *Out, int type,
	    const char *field_name, const char *zcolumn)
{
    int ltype, line;
    int ctype;
    int field;
    
    struct line_pnts *Points;
    struct line_cats *Cats;

    struct field_info *Fi;
    dbDriver *driver;
    dbString stmt;
    char buf[2000];
    int ncats, *cats, cat, *cex;

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

    db_init_string(&stmt);

    field = Vect_get_field_number(In, field_name);

    if (zcolumn) {
	Fi = Vect_get_field(Out, field);
	if (!Fi) {
	    G_warning(_("Database connection not defined for layer <%s>"),
		      field_name);
	    return -1;
	}

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

	/* column type must numeric */
	ctype = db_column_Ctype(driver, Fi->table, zcolumn);
	if (ctype == -1) {
	    G_warning(_("Column <%s> not found in table <%s>"),
		      zcolumn, Fi->table);
	    return -1;
	}
	if (ctype != DB_C_TYPE_INT && ctype != DB_C_TYPE_DOUBLE) {
	    G_warning(_("Column must be numeric"));
	    return -1;
	}

	db_begin_transaction(driver);

	/* select existing categories (layer) to array (array is sorted) */
	ncats = db_select_int(driver, Fi->table, Fi->key, NULL, &cats);
	G_debug(3, "Existing categories: %d", ncats);
    }

    line = 1;
    while (1) {
	ltype = Vect_read_next_line(In, Points, Cats);
	if (ltype == -1) {
	    G_warning(_("Unable to read vector map"));
	    return -1;
	}
	if (ltype == -2) {	/* EOF */
	    break;
	}

	if (G_verbose() > G_verbose_min() && (line - 1) % 1000 == 0) {
	    fprintf(stderr, "%7d\b\b\b\b\b\b\b", (line - 1));
	}

	if (!(ltype & type))
	    continue;

	if (field != -1 && !Vect_cat_get(Cats, field, &cat))
	    continue;

	/* get first cat */
	if (cat == -1) {
	    G_warning(_("Feature id %d has no category - skipping"), line);
	}
	else if (Cats->n_cats > 1) {
	    G_warning(_("Feature id %d has more categories. "
			"Using category %d."), line, field, cat);
	}

	if (zcolumn && ltype == GV_POINT && cat > -1) {
	    /* category exist in table ? */
	    cex = (int *)bsearch((void *)&cat, cats, ncats, sizeof(int),
				 srch);

	    /* store height to the attribute table */
	    if (ctype == DB_C_TYPE_INT)
		sprintf(buf, "update %s set %s = %d where cat = %d",
			Fi->table, zcolumn, (int)Points->z[0], cat);
	    else		/* double */
		sprintf(buf, "update %s set %s = %.8f where cat = %d",
			Fi->table, zcolumn, Points->z[0], cat);

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

	    if (cex) {
		if (db_execute_immediate(driver, &stmt) == DB_OK) {
		    /* TODO */
		}
	    }
	    else {		/* cat does not exist in table */
		G_warning(_("Record (cat %d) does not exist (not updated)"),
			  cat);
	    }
	}

	Vect_write_line(Out, ltype, Points, Cats);
	line++;
    }

    if (G_verbose() > G_verbose_min())
	fprintf(stderr, "\r");

    if (zcolumn) {
	db_commit_transaction(driver);

	G_free(cats);

	db_close_database_shutdown_driver(driver);
	db_free_string(&stmt);
    }

    Vect_destroy_line_struct(Points);
    Vect_destroy_cats_struct(Cats);

    return line - 1;
}
コード例 #24
0
ファイル: map.c プロジェクト: AsherBond/MondocosmOS
/*!
   \brief Copy all alive vector features from given layer of opened
   vector map to another opened vector map

   \param In input vector map
   \param field layer number (-1 for all layers)
   \param[out] Out output vector map

   \return 0 on success
   \return 1 on error
 */
int Vect_copy_map_lines_field(struct Map_info *In, int field,
			      struct Map_info *Out)
{
    int i, type, nlines, ret, left, rite, centroid;
    struct line_pnts *Points, *CPoints;
    struct line_cats *Cats, *CCats;

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

    if (Vect_level(In) < 1)
	G_fatal_error("Vect_copy_map_lines(): %s",
		      _("input vector map is not open"));

    ret = 0;
    /* Note: sometimes is important to copy on level 2 (pseudotopo centroids) 
     *       and sometimes on level 1 if build take too long time */
    if (Vect_level(In) >= 2) {
	nlines = Vect_get_num_lines(In);
	for (i = 1; i <= nlines; i++) {
	    if (!Vect_line_alive(In, i))
		continue;

	    type = Vect_read_line(In, Points, Cats, i);
	    if (type == -1) {
		G_warning(_("Unable to read vector map <%s>"),
			  Vect_get_full_name(In));
		ret = 1;
		break;
	    }
	    if (type == 0)
		continue;	/* dead line */

	    /* don't skips boundaries if field != -1 */
	    if (field != -1) {
		if (type & GV_BOUNDARY) {
		    if (Vect_cat_get(Cats, field, NULL) == 0) {
			int skip_bndry = 1;

			Vect_get_line_areas(In, i, &left, &rite);
			if (left < 0)
			    left = Vect_get_isle_area(In, abs(left));
			if (left > 0) {
			    if ((centroid =
				 Vect_get_area_centroid(In, left)) > 0) {
				Vect_read_line(In, CPoints, CCats, centroid);
				if (Vect_cat_get(CCats, field, NULL) != 0)
				    skip_bndry = 0;
			    }
			}
			if (skip_bndry) {
			    if (rite < 0)
				rite = Vect_get_isle_area(In, abs(rite));
			    if (rite > 0) {
				if ((centroid =
				     Vect_get_area_centroid(In, rite)) > 0) {
				    Vect_read_line(In, CPoints, CCats,
						   centroid);
				    if (Vect_cat_get(CCats, field, NULL) != 0)
					skip_bndry = 0;
				}
			    }
			}
			if (skip_bndry)
			    continue;
		    }
		}
		else if (Vect_cat_get(Cats, field, NULL) == 0)
		    continue;	/* different layer */
	    }

	    Vect_write_line(Out, type, Points, Cats);
	}
    }
    else {			/* Level 1 */
	Vect_rewind(In);
	while (1) {
	    type = Vect_read_next_line(In, Points, Cats);
	    if (type == -1) {
		G_warning(_("Unable to read vector map <%s>"),
			  Vect_get_full_name(In));
		ret = 1;
		break;
	    }
	    else if (type == -2) {	/* EOF */
		break;
	    }
	    else if (type == 0) {	/* dead line */
		continue;
	    }

	    /* don't skip boundaries if field != -1 */
	    if (field != -1 && !(type & GV_BOUNDARY) &&
		Vect_cat_get(Cats, field, NULL) == 0)
		continue;	/* different layer */

	    Vect_write_line(Out, type, Points, Cats);
	}
    }
    Vect_destroy_line_struct(Points);
    Vect_destroy_line_struct(CPoints);
    Vect_destroy_cats_struct(Cats);
    Vect_destroy_cats_struct(CCats);

    return ret;
}
コード例 #25
0
ファイル: plot.c プロジェクト: felipebetancur/grass-ci
/* Returns 0 - ok , 1 - error */
int
plot(int ctype, struct Map_info *Map, int type, int field,
     char *columns, int ncols, char *sizecol, int size, double scale,
     COLOR * ocolor, COLOR * colors, int y_center, double *max_reference,
     int do3d)
{
    int ltype, nlines, line, col, more, coltype, nselcols;
    double x, y, csize, len;
    struct line_pnts *Points;
    struct line_cats *Cats;
    int cat;
    double *val;
    char buf[2000];
    struct field_info *Fi;
    dbDriver *driver;
    dbValue *value;
    dbString sql;
    dbCursor cursor;
    dbTable *table;
    dbColumn *column;

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

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

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

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

    Vect_rewind(Map);

    nlines = Vect_get_num_lines(Map);

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

	if (!(ltype & type))
	    continue;

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

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

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

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

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

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

	db_close_cursor(&cursor);

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

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

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

    return 0;
}
コード例 #26
0
ファイル: gv3.c プロジェクト: rashadkm/grass_cmake
/*!
  \brief Load styles for geolines based on thematic mapping

  \param gv pointer to geovect structure
  \param colors pointer to Colors structure or NULL

  \return number of features defined by thematic mapping
  \return -1 on error
*/
int Gv_load_vect_thematic(geovect *gv, struct Colors *colors)
{
    geoline *gvt;

    struct Map_info Map;
    struct field_info *Fi;
    
    int nvals, cat, nlines, nskipped;
    int red, blu, grn;
    const char *str;
    const char *mapset;

    dbDriver *driver;
    dbValue value;
    
    if(!gv || !gv->tstyle || !gv->filename)
	return -1;

    mapset = G_find_vector2(gv->filename, "");
    if (!mapset) {
	G_fatal_error(_("Vector map <%s> not found"), gv->filename);
    }
    
    Vect_set_open_level(1);
    if (Vect_open_old(&Map, gv->filename, "") == -1) {
	G_fatal_error(_("Unable to open vector map <%s>"),
		      G_fully_qualified_name(gv->filename, mapset));
    }
    
    Fi = Vect_get_field(&Map, gv->tstyle->layer);
    if (!Fi) {
	G_warning(_("Database connection not defined for layer %d"),
		  gv->tstyle->layer);
    }
    else {
      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);
    }
    G_message(_("Loading thematic vector layer <%s>..."),
	      G_fully_qualified_name(gv->filename, mapset));
    nlines = nskipped = 0;
    for(gvt = gv->lines; gvt; gvt = gvt->next) {
	gvt->style = (gvstyle *) G_malloc(sizeof(gvstyle));
	G_zero(gvt->style, sizeof(gvstyle));
	
	/* use default style */
	gvt->style->color  = gv->style->color;
	gvt->style->symbol = gv->style->symbol;
	gvt->style->size   = gv->style->size;
	gvt->style->width  = gv->style->width;

	cat = -1;
	if (gvt->cats)
	    Vect_cat_get(gvt->cats, gv->tstyle->layer, &cat);
	if (cat < 0) {
	    nskipped++;
	    continue;
	}
	
	/* color */
	if (colors) {
	    if (!Rast_get_c_color((const CELL *) &cat, &red, &grn, &blu, colors)) {
		G_warning(_("No color rule defined for category %d"), cat);
		gvt->style->color = gv->style->color;
	    }
	    gvt->style->color = (red & RED_MASK) + ((int)((grn) << 8) & GRN_MASK) +
		((int)((blu) << 16) & BLU_MASK);
	}
	
	if (gv->tstyle->color_column) {
	    nvals = db_select_value(driver, Fi->table, Fi->key, cat, gv->tstyle->color_column, &value);
	    if (nvals < 1)
		continue;
	    str = db_get_value_string(&value);
	    if (!str)
		continue;
	    if (G_str_to_color(str, &red, &grn, &blu) != 1) {
		G_warning(_("Invalid color definition (%s)"),
			  str);
		gvt->style->color = gv->style->color;
	    }
	    else {
		gvt->style->color = (red & RED_MASK) + ((int)((grn) << 8) & GRN_MASK) +
		    ((int)((blu) << 16) & BLU_MASK);
	    }
	}
	
	/* width */
	if (gv->tstyle->width_column) {
	    nvals = db_select_value(driver, Fi->table, Fi->key, cat, gv->tstyle->width_column, &value);
	    if (nvals < 1)
		continue;
	    gvt->style->width = db_get_value_int(&value);
	}

	nlines++;
    }

    if (nskipped > 0)
	G_warning(_("%d features without category. "
		    "Unable to determine color rules for features without category."),
		  nskipped);
    
    return nlines;
}
コード例 #27
0
ファイル: main.c プロジェクト: AsherBond/MondocosmOS
int main(int argc, char *argv[])
{
    int i, j, nlines, type, field, cat;
    int fd;

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

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

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

    G_gisinit(argv[0]);

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

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

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

    field_opt = G_define_standard_option(G_OPT_V_FIELD);

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

    where_opt = G_define_standard_option(G_OPT_DB_WHERE);

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


    field = atoi(field_opt->answer);

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

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

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

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

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

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

    out_type = Rast_get_map_type(fd);

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

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

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

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

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

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

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

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

    point_cnt = outside_cnt = nocat_cnt = 0;

    nlines = Vect_get_num_lines(&Map);

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    cur_row = -1;

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

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

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

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

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

    db_begin_transaction(driver);

    norec_cnt = update_cnt = upderr_cnt = dupl_cnt = 0;

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

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

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

	db_set_string(&stmt, buf);

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

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

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

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

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

    exit(EXIT_SUCCESS);
}
コード例 #28
0
ファイル: trans_digit.c プロジェクト: GRASS-GIS/grass-ci
int transform_digit_file(struct Map_info *Old, struct Map_info *New,
                         double ztozero, int swap_xy, int swap_xz,
                         int swap_yz, int swap_after,
                         double *trans_params_def, char **columns, int field)
{
    int i, type, cat, line, ret;
    int verbose, format;
    unsigned int j;
    double *trans_params;
    double ang, x, y, tmp;
    static struct line_pnts *Points;
    static struct line_cats *Cats;

    /* db */
    struct field_info *fi;
    int ctype;
    dbDriver *driver;
    dbValue val;

    cat = -1;			/* dummy value for debugging */

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

    driver = NULL;
    fi = NULL;
    if (field > 0) {
	fi = Vect_get_field(Old, field);

	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);

	trans_params = (double *)G_calloc(IDX_ZROT + 1, sizeof(double));
    }
    else {
	trans_params = trans_params_def;
	ang = PI * trans_params[IDX_ZROT] / 180;
    }

    line = 0;
    ret = 1;
    format = G_info_format();
    verbose = G_verbose() > G_verbose_min();
    while (TRUE) {
	type = Vect_read_next_line(Old, Points, Cats);

	if (type == -1)	{	/* error */
	    ret = 0;
	    break;
	}

	if (type == -2) {	/* EOF */
	    ret = 1;
	    break;
	}

	if (field != -1 && !Vect_cat_get(Cats, field, NULL))
	    continue;
	
	if (verbose && line % 1000 == 0) {
	    if (format == G_INFO_FORMAT_PLAIN)
		fprintf(stderr, "%d..", line);
	    else
		fprintf(stderr, "%11d\b\b\b\b\b\b\b\b\b\b\b", line);
	}

        if (swap_xy && !swap_after) {
            for (i = 0; i < Points->n_points; i++) {
                x = Points->x[i];
                Points->x[i] = Points->y[i];
                Points->y[i] = x;
            }
        }
        if (swap_xz && !swap_after) {
            for (i = 0; i < Points->n_points; i++) {
                tmp = Points->z[i];
                Points->z[i] = Points->x[i];
                Points->x[i] = tmp;
            }
        }
        if (swap_yz && !swap_after) {
            for (i = 0; i < Points->n_points; i++) {
                tmp = Points->z[i];
                Points->z[i] = Points->y[i];
                Points->y[i] = tmp;
            }
        }

	/* get transformation parameters */
	if (field > 0) {
	    Vect_cat_get(Cats, field, &cat);	/* get first category */
	    if (cat > -1) {
		for (j = 0; j <= IDX_ZROT; j++) {
		    if (columns[j] == NULL) {
			trans_params[j] = trans_params_def[j];
			continue;
		    }
		    ctype = db_column_Ctype(driver, fi->table, columns[j]);
		    switch (ctype) {
		    case DB_C_TYPE_INT:
		    case DB_C_TYPE_DOUBLE:
		    case DB_C_TYPE_STRING:
			break;
		    case -1:
			G_fatal_error(_("Column <%s> not found in table <%s>"),
				      columns[j], fi->table);
		    default:
			G_fatal_error(_("Unsupported column type of <%s>"),
				      columns[j]);
		    }
		    if (db_select_value
			(driver, fi->table, fi->key, cat, columns[j], &val) != 1
			|| db_test_value_isnull(&val)) {
			trans_params[j] = trans_params_def[j];

			G_warning(_("Unable to select value for category %d from table <%s>, column <%s>. "
				   "For category %d using default transformation parameter %.3f."),
				  cat, fi->table, columns[j], cat,
				  trans_params[j]);
		    }
		    else {
			trans_params[j] = db_get_value_as_double(&val, ctype);
		    }
		}
	    }
	    else {
		G_warning(_("No category number defined. Using default transformation parameters."));

		for (j = 0; j <= IDX_ZROT; j++) {
		    trans_params[j] = trans_params_def[j];
		}
	    }
	    ang = PI * trans_params[IDX_ZROT] / 180;
	}

	/* transform points */
	for (i = 0; i < Points->n_points; i++) {
	    G_debug(3, "idx=%d, cat=%d, xshift=%g, yshift=%g, zshift=%g, "
		    "xscale=%g, yscale=%g, zscale=%g, zrot=%g",
		    i, cat, trans_params[IDX_XSHIFT],
		    trans_params[IDX_YSHIFT], trans_params[IDX_ZSHIFT],
		    trans_params[IDX_XSCALE], trans_params[IDX_YSCALE],
		    trans_params[IDX_ZSCALE], trans_params[IDX_ZROT]);

	    /* transform point */
	    x = trans_params[IDX_XSHIFT] +
		trans_params[IDX_XSCALE] * Points->x[i] * cos(ang)
		- trans_params[IDX_YSCALE] * Points->y[i] * sin(ang);
	    y = trans_params[IDX_YSHIFT] +
		trans_params[IDX_XSCALE] * Points->x[i] * sin(ang)
		+ trans_params[IDX_YSCALE] * Points->y[i] * cos(ang);
	    Points->x[i] = x;
	    Points->y[i] = y;

	    /* ztozero shifts oldmap z to zero, zshift shifts rescaled object
	     * to target elevation: */
	    Points->z[i] =
		((Points->z[i] + ztozero) * trans_params[IDX_ZSCALE]) +
		trans_params[IDX_ZSHIFT];

            if (swap_after) {
                if (swap_xy) {
                    tmp = Points->x[i];
                    Points->x[i] = Points->y[i];
                    Points->y[i] = tmp;
                }
                if (swap_xz) {
                    tmp = Points->z[i];
                    Points->z[i] = Points->x[i];
                    Points->x[i] = tmp;
                }
                if (swap_yz) {
                    tmp = Points->z[i];
                    Points->z[i] = Points->y[i];
                    Points->y[i] = tmp;
                }
            }
	}

	Vect_write_line(New, type, Points, Cats);
	line++;
    }

    if (verbose && format != G_INFO_FORMAT_PLAIN)
	fprintf(stderr, "\r");
    
    if (field > 0) {
	db_close_database_shutdown_driver(driver);
	G_free((void *)trans_params);
    }
    
    return ret;
}
コード例 #29
0
ファイル: attr.c プロジェクト: felipebetancur/grass-ci
int display_attr(struct Map_info *Map, int type, char *attrcol,
		 struct cat_list *Clist, LATTR *lattr, int chcat)
{
    int i, ltype, more;
    struct line_pnts *Points;
    struct line_cats *Cats;
    int cat;
    char buf[2000];
    struct field_info *fi;
    dbDriver *driver;
    dbString stmt, valstr, text;
    dbCursor cursor;
    dbTable *table;
    dbColumn *column;

    G_debug(2, "attr()");

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

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

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

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

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

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

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

	if (chcat) {
	    int found = 0;

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

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

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

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

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

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

		nrows = db_get_num_rows(&cursor);

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

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

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

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

		db_close_cursor(&cursor);
		ncats++;
	    }

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

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

    return 0;
}
コード例 #30
0
ファイル: main.c プロジェクト: rashadkm/grass_cmake
int main(int argc, char *argv[])
{
    int i, j, precision, field, type, nlines;
    int do_attr = 0, attr_cols[8], attr_size = 0, db_open = 0, cnt = 0;

    double width, radius;
    struct Option *in_opt, *out_opt, *prec_opt, *type_opt, *attr_opt,
	*field_opt;
    struct GModule *module;
    struct Map_info In;
    struct bound_box box;

    /* vector */
    struct line_pnts *Points;
    struct line_cats *Cats;

    /* attribs */
    dbDriver *Driver = NULL;
    dbHandle handle;
    dbTable *Table;
    dbString dbstring;
    struct field_info *Fi;

    /* init */
    G_gisinit(argv[0]);

    /* parse command-line */
    module = G_define_module();
    module->description = _("Exports a vector map to SVG file.");
    G_add_keyword(_("vector"));
    G_add_keyword(_("export"));

    in_opt = G_define_standard_option(G_OPT_V_INPUT);

    field_opt = G_define_standard_option(G_OPT_V_FIELD_ALL);

    out_opt = G_define_standard_option(G_OPT_F_OUTPUT);
    out_opt->description = _("Name for SVG output file");

    type_opt = G_define_option();
    type_opt->key = "type";
    type_opt->type = TYPE_STRING;
    type_opt->required = YES;
    type_opt->multiple = NO;
    type_opt->answer = "poly";
    type_opt->options = "poly,line,point";
    type_opt->label = _("Output type");
    type_opt->description = _("Defines which feature-type will be extracted");

    prec_opt = G_define_option();
    prec_opt->key = "precision";
    prec_opt->type = TYPE_INTEGER;
    prec_opt->required = NO;
    prec_opt->answer = "6";
    prec_opt->multiple = NO;
    prec_opt->description = _("Coordinate precision");

    attr_opt = G_define_standard_option(G_OPT_DB_COLUMNS);
    attr_opt->key = "attribute";
    attr_opt->required = NO;
    attr_opt->multiple = YES;
    attr_opt->description = _("Attribute(s) to include in output SVG");
    
    if (G_parser(argc, argv))
	exit(EXIT_FAILURE);

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

    if (type_opt->answer[0] == 'l') {
        type = TYPE_LINE;
    }
    else {
        if (type_opt->answer[2] == 'l')
            type = TYPE_POLY;
        else
            type = TYPE_POINT;
    }
            
    /* override coordinate precision if any */
    precision = atof(prec_opt->answer);
    if (precision < 0) {
	G_fatal_error(_("Precision must not be negative"));
    }
    if (precision > 15) {
	G_fatal_error(_("Precision must not be higher than 15"));
    }

    /* open input vector */
    Vect_set_open_level(2);
    if (Vect_open_old2(&In, in_opt->answer, "", field_opt->answer) < 0)
	G_fatal_error(_("Unable to open vector map <%s>"), in_opt->answer);

    /* parse field number */
    field = Vect_get_field_number(&In, field_opt->answer);

    /* open db-driver to attribs */
    db_init_string(&dbstring);

    /* check for requested field */
    Fi = Vect_get_field(&In, field);
    if (Fi != NULL) {
	Driver = db_start_driver(Fi->driver);
	if (Driver == NULL) {
	    G_fatal_error(_("Unable to start driver <%s>"), Fi->driver);
	}

	/* open db */
	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_set_string(&dbstring, Fi->table);
	if (db_describe_table(Driver, &dbstring, &Table) != DB_OK) {
	    G_fatal_error(_("Unable to describe table <%s>"), Fi->table);
	}

	/* define column-indices for columns to extract */
	dbColumn *Column;

	for (i = 0; i < db_get_table_number_of_columns(Table); i++) {
	    Column = db_get_table_column(Table, i);
	    if (attr_opt->answer != NULL) {
		for (j = 0; attr_opt->answers[j] != NULL; j++) {
		    if (G_strcasecmp(attr_opt->answers[j],
				     db_get_column_name(Column)) == 0) {
			attr_cols[attr_size] = i;
			attr_size += 1;
			break;
		    }
		}
	    }
	}
	do_attr = 1;
	db_open = 1;
    }

    /* parse bounding box and define default stroke-width, radius */
    Vect_get_map_box(&In, &box);
    if ((box.E - box.W) >= (box.N - box.S)) {
	radius = (box.E - box.W) * RADIUS_SCALE;
	width = (box.E - box.W) * WIDTH_SCALE;
    }
    else {
	radius = (box.N - box.S) * RADIUS_SCALE;
	width = (box.N - box.S) * WIDTH_SCALE;
    }

    /* open output SVG-file and print SVG-header with viewBox and Namenspaces */
    if ((fpsvg = fopen(out_opt->answer, "w")) == NULL) {
	G_fatal_error(_("Unable to create SVG file <%s>"), out_opt->answer);
    }

    fprintf(fpsvg, "<svg xmlns=\"%s\" xmlns:xlink=\"%s\" xmlns:gg=\"%s\" ",
	    SVG_NS, XLINK_NS, GRASS_NS);
    fprintf(fpsvg, "viewBox=\"%.*f %.*f %.*f %.*f\">\n",
	    precision, box.W,
	    precision, box.N * -1,
	    precision, box.E - box.W, precision, box.N - box.S);
    fprintf(fpsvg, "<title>v.out.svg %s %s</title>\n", in_opt->answer,
	    out_opt->answer);

    nlines = Vect_get_num_lines(&In);
    
    /* extract areas if any or requested */
    if (type == TYPE_POLY) {
	if (Vect_get_num_areas(&In) == 0) {
	    G_warning(_("No areas found, skipping %s"), "type=poly");
	}
	else {
            int nareas;
            
            nareas = Vect_get_num_areas(&In);
	    /* extract area as paths */
	    fprintf(fpsvg,
		    " <g id=\"%s\" fill=\"#CCC\" stroke=\"#000\" stroke-width=\"%.*f\" >\n",
		    G_Areas, precision, width);
	    for (i = 1; i <= nareas; i++) {
		G_percent(i, nareas, 5);

		/* skip areas without centroid */
		if (Vect_get_area_centroid(&In, i) == 0) {
		    G_warning(_("Skipping area %d without centroid"), i);
		    continue;
		}

		/* extract attribs, parse area */
		Vect_get_area_cats(&In, i, Cats);
		fprintf(fpsvg, "  <path ");
		if (Cats->n_cats > 0) {
		    mk_attribs(Cats->cat[0], Fi, Driver, Table, attr_cols,
			       attr_size, do_attr);
		}
		fprintf(fpsvg, "d=\"");

		Vect_get_area_points(&In, i, Points);
		mk_path(Points, precision);

		/* append islands if any within current path */
		for (j = 0; j < Vect_get_area_num_isles(&In, i); j++) {
		    Vect_get_isle_points(&In, Vect_get_area_isle(&In, i, j),
					 Points);
		    mk_path(Points, precision);
		}
		fprintf(fpsvg, "\" />\n");
		cnt += 1;
	    }
	    fprintf(fpsvg, " </g>\n");
	    G_message(_("%d areas extracted"), cnt);
	}
    }
    
    /* extract points if requested */
    if (type == TYPE_POINT) {
	if (Vect_get_num_primitives(&In, GV_POINTS) == 0) {
	    G_warning(_("No points found, skipping %s"), "type=point");
	}
	else {
	    /* extract points as circles */
	    fprintf(fpsvg, " <g id=\"%s\" fill=\"#FC0\" stroke=\"#000\" "
		    "stroke-width=\"%.*f\" >\n", G_Points, precision, width);
	    for (i = 1; i <= nlines; i++) {
		G_percent(i, nlines, 5);
                
		if (!(Vect_read_line(&In, Points, Cats, i) & GV_POINTS))
                    continue;
                
		if (field != -1 && !Vect_cat_get(Cats, field, NULL))
		    continue;
                
		for (j = 0; j < Points->n_points; j++) {
		    fprintf(fpsvg, "  <circle ");
		    if (Cats->n_cats > 0) {
			mk_attribs(Cats->cat[j], Fi, Driver, Table, attr_cols,
				   attr_size, do_attr);
		    }
		    fprintf(fpsvg, "cx=\"%.*f\" cy=\"%.*f\" r=\"%.*f\" />\n",
			    precision, Points->x[j],
			    precision, Points->y[j] * -1, precision, radius);
		    cnt += 1;
		}

	    }
	    fprintf(fpsvg, " </g>\n");
	    G_message(_("%d points extracted"), cnt);
	}
    }
    
    /* extract lines if requested */
    if (type == TYPE_LINE) {
	if (Vect_get_num_primitives(&In, GV_LINES) == 0) {
	    G_warning(_("No lines found, skipping %s"), "type=line");
	}
	else {
	    /* extract lines as paths */
	    fprintf(fpsvg, " <g id=\"%s\" fill=\"none\" stroke=\"#000\" "
		    "stroke-width=\"%.*f\" >\n", G_Lines, precision, width);
	    for (i = 1; i <= nlines; i++) {
		G_percent(i, nlines, 5);
                
		if (!(Vect_read_line(&In, Points, Cats, i) & GV_LINES))
                    continue;
                
                if (field != -1 && !Vect_cat_get(Cats, field, NULL))
		    continue;
                
		fprintf(fpsvg, "  <path ");
		if (Cats->n_cats > 0) {
		    mk_attribs(Cats->cat[0], Fi, Driver, Table,
			       attr_cols, attr_size, do_attr);
		}

		fprintf(fpsvg, "d=\"");
		mk_path(Points, precision);
		fprintf(fpsvg, "\" />\n");
		cnt += 1;
	    }
	    fprintf(fpsvg, " </g>\n");
	    G_message(_("%d lines extracted"), cnt);
	}
    }
    /* finish code */
    fprintf(fpsvg, "</svg>\n");

    if (db_open == 1) {
	/* close database handle */
	db_close_database(Driver);
	db_shutdown_driver(Driver);
    }

    /* close SVG-file */
    fclose(fpsvg);
    
    exit(EXIT_SUCCESS);
}