int main(int argc, char *argv[]) { char *p; int i, j, k; int method, half, use_catno; const char *mapset; struct GModule *module; struct Option *point_opt, /* point vector */ *area_opt, /* area vector */ *point_type_opt, /* point type */ *point_field_opt, /* point layer */ *area_field_opt, /* area layer */ *method_opt, /* stats method */ *point_column_opt, /* point column for stats */ *count_column_opt, /* area column for point count */ *stats_column_opt, /* area column for stats result */ *fs_opt; /* field separator for printed output */ struct Flag *print_flag; char *fs; struct Map_info PIn, AIn; int point_type, point_field, area_field; struct line_pnts *Points; struct line_cats *ACats, *PCats; AREA_CAT *Area_cat; int pline, ptype, count; int area, nareas, nacats, nacatsalloc; int ctype, nrec; struct field_info *PFi, *AFi; dbString stmt; dbDriver *Pdriver, *Adriver; char buf[2000]; int update_ok, update_err; struct boxlist *List; struct bound_box box; dbCatValArray cvarr; dbColumn *column; struct pvalcat { double dval; int catno; } *pvalcats; int npvalcats, npvalcatsalloc; stat_func *statsvalue = NULL; double result; column = NULL; G_gisinit(argv[0]); module = G_define_module(); G_add_keyword(_("vector")); G_add_keyword(_("attribute table")); G_add_keyword(_("database")); G_add_keyword(_("univariate statistics")); G_add_keyword(_("zonal statistics")); module->description = _("Count points in areas, calculate statistics from point attributes."); point_opt = G_define_standard_option(G_OPT_V_INPUT); point_opt->key = "points"; point_opt->description = _("Name of existing vector map with points"); /* point_opt->guisection = _("Required"); */ area_opt = G_define_standard_option(G_OPT_V_INPUT); area_opt->key = "areas"; area_opt->description = _("Name of existing vector map with areas"); /* area_opt->guisection = _("Required"); */ point_type_opt = G_define_standard_option(G_OPT_V_TYPE); point_type_opt->key = "type"; point_type_opt->options = "point,centroid"; point_type_opt->answer = "point"; point_type_opt->label = _("Feature type"); point_type_opt->required = NO; point_field_opt = G_define_standard_option(G_OPT_V_FIELD); point_field_opt->key = "player"; point_field_opt->label = _("Layer number for points map"); area_field_opt = G_define_standard_option(G_OPT_V_FIELD); area_field_opt->key = "alayer"; area_field_opt->label = _("Layer number for area map"); method_opt = G_define_option(); method_opt->key = "method"; method_opt->type = TYPE_STRING; method_opt->required = NO; method_opt->multiple = NO; p = G_malloc(1024); for (i = 0; menu[i].name; i++) { if (i) strcat(p, ","); else *p = 0; strcat(p, menu[i].name); } method_opt->options = p; method_opt->description = _("Method for aggregate statistics"); point_column_opt = G_define_standard_option(G_OPT_DB_COLUMN); point_column_opt->key = "pcolumn"; point_column_opt->required = NO; point_column_opt->multiple = NO; point_column_opt->label = _("Column name of points map to use for statistics"); point_column_opt->description = _("Column of points map must be numeric"); count_column_opt = G_define_option(); count_column_opt->key = "ccolumn"; count_column_opt->type = TYPE_STRING; count_column_opt->required = NO; count_column_opt->multiple = NO; count_column_opt->label = _("Column name to upload points count"); count_column_opt->description = _("Column to hold points count, must be of type integer, will be created if not existing"); stats_column_opt = G_define_option(); stats_column_opt->key = "scolumn"; stats_column_opt->type = TYPE_STRING; stats_column_opt->required = NO; stats_column_opt->multiple = NO; stats_column_opt->label = _("Column name to upload statistics"); stats_column_opt->description = _("Column to hold statistics, must be of type double, will be created if not existing"); fs_opt = G_define_standard_option(G_OPT_F_SEP); print_flag = G_define_flag(); print_flag->key = 'p'; print_flag->label = _("Print output to stdout, do not update attribute table"); print_flag->description = _("First column is always area category"); if (G_parser(argc, argv)) exit(EXIT_FAILURE); point_type = Vect_option_to_types(point_type_opt); point_field = atoi(point_field_opt->answer); area_field = atoi(area_field_opt->answer); if (print_flag->answer) /* get field separator */ fs = G_option_to_separator(fs_opt); else fs = NULL; /* check for stats */ if (method_opt->answer) { if (!point_column_opt->answer) { G_fatal_error("Method but no point column selected"); } if (!print_flag->answer && !stats_column_opt->answer) G_fatal_error("Name for stats column is missing"); } if (point_column_opt->answer) { if (!method_opt->answer) G_fatal_error("No method for statistics selected"); if (!print_flag->answer && !stats_column_opt->answer) G_fatal_error("Name for stats column is missing"); } /* Open points vector */ if ((mapset = G_find_vector2(point_opt->answer, "")) == NULL) G_fatal_error(_("Vector map <%s> not found"), point_opt->answer); Vect_set_open_level(2); if (Vect_open_old(&PIn, point_opt->answer, mapset) < 0) G_fatal_error(_("Unable to open vector map <%s>"), point_opt->answer); /* Open areas vector */ if ((mapset = G_find_vector2(area_opt->answer, "")) == NULL) G_fatal_error(_("Vector map <%s> not found"), area_opt->answer); if (!print_flag->answer && strcmp(mapset, G_mapset()) != 0) G_fatal_error(_("Vector map <%s> is not in user mapset and cannot be updated"), area_opt->answer); Vect_set_open_level(2); if (Vect_open_old(&AIn, area_opt->answer, mapset) < 0) G_fatal_error(_("Unable to open vector map <%s>"), area_opt->answer); method = -1; use_catno = 0; half = 0; if (method_opt->answer) { /* get the method */ for (method = 0; (p = menu[method].name); method++) if ((strcmp(p, method_opt->answer) == 0)) break; if (!p) { G_warning(_("<%s=%s> unknown %s"), method_opt->key, method_opt->answer, method_opt->answer); G_usage(); exit(EXIT_FAILURE); } /* establish the statsvalue routine */ statsvalue = menu[method].method; /* category number of lowest/highest value */ if ((strcmp(menu[method].name, menu[5].name) == 0) || (strcmp(menu[method].name, menu[7].name) == 0)) use_catno = 1; G_debug(1, "method: %s, use cat value: %s", menu[method].name, (use_catno == 1 ? "yes" : "no")); } /* Open database driver */ db_init_string(&stmt); Adriver = NULL; if (!print_flag->answer) { AFi = Vect_get_field(&AIn, area_field); if (AFi == NULL) G_fatal_error(_("Database connection not defined for layer %d"), area_field); Adriver = db_start_driver_open_database(AFi->driver, AFi->database); if (Adriver == NULL) G_fatal_error(_("Unable to open database <%s> with driver <%s>"), AFi->database, AFi->driver); if (!count_column_opt->answer) G_fatal_error(_("ccolumn is required to upload point counts")); /* check if count column exists */ G_debug(1, "check if count column exists"); db_get_column(Adriver, AFi->table, count_column_opt->answer, &column); if (column) { /* check count column type */ if (db_column_Ctype(Adriver, AFi->table, count_column_opt->answer) != DB_C_TYPE_INT) G_fatal_error(_("ccolumn must be of type integer")); db_free_column(column); column = NULL; } else { /* create count column */ /* db_add_column() exists but is not implemented, * see lib/db/stubs/add_col.c */ sprintf(buf, "alter table %s add column %s integer", AFi->table, count_column_opt->answer); db_set_string(&stmt, buf); if (db_execute_immediate(Adriver, &stmt) != DB_OK) G_fatal_error(_("Unable to add column <%s>"), count_column_opt->answer); } if (method_opt->answer) { if (!stats_column_opt->answer) G_fatal_error(_("scolumn is required to upload point stats")); /* check if stats column exists */ G_debug(1, "check if stats column exists"); db_get_column(Adriver, AFi->table, stats_column_opt->answer, &column); if (column) { /* check stats column type */ if (db_column_Ctype (Adriver, AFi->table, stats_column_opt->answer) != DB_C_TYPE_DOUBLE) G_fatal_error(_("scolumn must be of type double")); db_free_column(column); column = NULL; } else { /* create stats column */ /* db_add_column() exists but is not implemented, * see lib/db/stubs/add_col.c */ sprintf(buf, "alter table %s add column %s double", AFi->table, stats_column_opt->answer); db_set_string(&stmt, buf); if (db_execute_immediate(Adriver, &stmt) != DB_OK) G_fatal_error(_("Unable to add column <%s>"), stats_column_opt->answer); } } } else AFi = NULL; Pdriver = NULL; if (method_opt->answer) { G_verbose_message(_("collecting attributes from points vector...")); PFi = Vect_get_field(&PIn, point_field); if (PFi == NULL) G_fatal_error(_("Database connection not defined for layer %d"), point_field); Pdriver = db_start_driver_open_database(PFi->driver, PFi->database); if (Pdriver == NULL) G_fatal_error(_("Unable to open database <%s> with driver <%s>"), PFi->database, PFi->driver); /* check if point column exists */ db_get_column(Pdriver, PFi->table, point_column_opt->answer, &column); if (column) { db_free_column(column); column = NULL; } else { G_fatal_error(_("Column <%s> not found in table <%s>"), point_column_opt->answer, PFi->table); } /* Check column type */ ctype = db_column_Ctype(Pdriver, PFi->table, point_column_opt->answer); if (ctype == DB_C_TYPE_INT) half = menu[method].half; else if (ctype == DB_C_TYPE_DOUBLE) half = 0; else G_fatal_error(_("column for points vector must be numeric")); db_CatValArray_init(&cvarr); nrec = db_select_CatValArray(Pdriver, PFi->table, PFi->key, point_column_opt->answer, NULL, &cvarr); G_debug(1, "selected values = %d", nrec); db_close_database_shutdown_driver(Pdriver); } Points = Vect_new_line_struct(); ACats = Vect_new_cats_struct(); PCats = Vect_new_cats_struct(); List = Vect_new_boxlist(0); /* Allocate space ( may be more than needed (duplicate cats and elements without cats) ) */ if ((nareas = Vect_get_num_areas(&AIn)) <= 0) G_fatal_error("No areas in area input vector"); nacatsalloc = nareas; Area_cat = (AREA_CAT *) G_calloc(nacatsalloc, sizeof(AREA_CAT)); /* Read all cats from 'area' */ nacats = 0; for (area = 1; area <= nareas; area++) { Vect_get_area_cats(&AIn, area, ACats); if (ACats->n_cats <= 0) continue; for (i = 0; i < ACats->n_cats; i++) { if (ACats->field[i] == area_field) { Area_cat[nacats].area_cat = ACats->cat[i]; Area_cat[nacats].count = 0; Area_cat[nacats].nvalues = 0; Area_cat[nacats].nalloc = 0; nacats++; if (nacats >= nacatsalloc) { nacatsalloc += 100; Area_cat = (AREA_CAT *) G_realloc(Area_cat, nacatsalloc * sizeof(AREA_CAT)); } } } } G_debug(1, "%d cats loaded from vector (including duplicates)", nacats); /* Sort by category */ qsort((void *)Area_cat, nacats, sizeof(AREA_CAT), cmp_area); /* remove duplicate categories */ for (i = 1; i < nacats; i++) { if (Area_cat[i].area_cat == Area_cat[i - 1].area_cat) { for (j = i; j < nacats - 1; j++) { Area_cat[j].area_cat = Area_cat[j + 1].area_cat; } nacats--; } } G_debug(1, "%d cats loaded from vector (unique)", nacats); /* Go through all areas in area vector and find points in points vector * falling into the area */ npvalcatsalloc = 10; npvalcats = 0; pvalcats = (struct pvalcat *)G_calloc(npvalcatsalloc, sizeof(struct pvalcat)); G_message(_("Selecting points for each area...")); count = 0; for (area = 1; area <= nareas; area++) { dbCatVal *catval; G_debug(3, "area = %d", area); G_percent(area, nareas, 2); Vect_get_area_cats(&AIn, area, ACats); if (ACats->n_cats <= 0) continue; /* select points by box */ Vect_get_area_box(&AIn, area, &box); box.T = PORT_DOUBLE_MAX; box.B = -PORT_DOUBLE_MAX; Vect_select_lines_by_box(&PIn, &box, point_type, List); G_debug(4, "%d points selected by box", List->n_values); /* For each point in box check if it is in the area */ for (i = 0; i < List->n_values; i++) { pline = List->id[i]; G_debug(4, "%d: point %d", i, pline); ptype = Vect_read_line(&PIn, Points, PCats, pline); if (!(ptype & point_type)) continue; /* point in area */ if (Vect_point_in_area(Points->x[0], Points->y[0], &AIn, area, &box)) { AREA_CAT *area_info, search_ai; int tmp_cat; /* stats on point column */ if (method_opt->answer) { npvalcats = 0; tmp_cat = -1; for (j = 0; j < PCats->n_cats; j++) { if (PCats->field[j] == point_field) { if (tmp_cat >= 0) G_debug(3, "More cats found in point layer (point=%d)", pline); tmp_cat = PCats->cat[j]; /* find cat in array */ db_CatValArray_get_value(&cvarr, tmp_cat, &catval); if (catval) { pvalcats[npvalcats].catno = tmp_cat; switch (cvarr.ctype) { case DB_C_TYPE_INT: pvalcats[npvalcats].dval = catval->val.i; npvalcats++; break; case DB_C_TYPE_DOUBLE: pvalcats[npvalcats].dval = catval->val.d; npvalcats++; break; } if (npvalcats >= npvalcatsalloc) { npvalcatsalloc += 10; pvalcats = (struct pvalcat *)G_realloc(pvalcats, npvalcatsalloc * sizeof (struct pvalcat)); } } } } } /* update count for all area cats of given field */ search_ai.area_cat = -1; for (j = 0; j < ACats->n_cats; j++) { if (ACats->field[j] == area_field) { if (search_ai.area_cat >= 0) G_debug(3, "More cats found in area layer (area=%d)", area); search_ai.area_cat = ACats->cat[j]; /* find cat in array */ area_info = (AREA_CAT *) bsearch((void *)&search_ai, Area_cat, nacats, sizeof(AREA_CAT), cmp_area); if (area_info->area_cat != search_ai.area_cat) G_fatal_error(_("could not find area category %d"), search_ai.area_cat); /* each point is counted once, also if it has * more than one category or no category * OK? */ area_info->count++; if (method_opt->answer) { /* ensure enough space */ if (area_info->nvalues + npvalcats >= area_info->nalloc) { if (area_info->nalloc == 0) { area_info->nalloc = npvalcats + 10; area_info->values = (double *)G_calloc(area_info->nalloc, sizeof(double)); area_info->cats = (int *)G_calloc(area_info->nalloc, sizeof(int)); } else area_info->nalloc += area_info->nvalues + npvalcats + 10; area_info->values = (double *)G_realloc(area_info->values, area_info->nalloc * sizeof(double)); area_info->cats = (int *)G_realloc(area_info->cats, area_info->nalloc * sizeof(int)); } for (k = 0; k < npvalcats; k++) { area_info->cats[area_info->nvalues] = pvalcats[k].catno; area_info->values[area_info->nvalues] = pvalcats[k].dval; area_info->nvalues++; } } } } count++; } } /* next point in box */ } /* next area */ G_debug(1, "count = %d", count); /* release catval array */ if (method_opt->answer) db_CatValArray_free(&cvarr); Vect_close(&PIn); /* Update table or print to stdout */ if (print_flag->answer) { /* print header */ fprintf(stdout, "area_cat%scount", fs); if (method_opt->answer) fprintf(stdout, "%s%s", fs, menu[method].name); fprintf(stdout, "\n"); } else { G_message("Updating attributes for area vector..."); update_err = update_ok = 0; } if (Adriver) db_begin_transaction(Adriver); for (i = 0; i < nacats; i++) { if (!print_flag->answer) G_percent(i, nacats, 2); result = 0; if (Area_cat[i].count > 0 && method_opt->answer) { /* get stats */ statsvalue(&result, Area_cat[i].values, Area_cat[i].nvalues, NULL); if (half) result += 0.5; else if (use_catno) result = Area_cat[i].cats[(int)result]; } if (print_flag->answer) { fprintf(stdout, "%d%s%d", Area_cat[i].area_cat, fs, Area_cat[i].count); if (method_opt->answer) { if (Area_cat[i].count > 0) fprintf(stdout, "%s%.15g", fs, result); else fprintf(stdout, "%snull", fs); } fprintf(stdout, "\n"); } else { sprintf(buf, "update %s set %s = %d", AFi->table, count_column_opt->answer, Area_cat[i].count); db_set_string(&stmt, buf); if (method_opt->answer) { if (Area_cat[i].count > 0) sprintf(buf, " , %s = %.15g", stats_column_opt->answer, result); else sprintf(buf, " , %s = null", stats_column_opt->answer); db_append_string(&stmt, buf); } sprintf(buf, " where %s = %d", AFi->key, Area_cat[i].area_cat); db_append_string(&stmt, buf); G_debug(2, "SQL: %s", db_get_string(&stmt)); if (db_execute_immediate(Adriver, &stmt) == DB_OK) { update_ok++; } else { update_err++; } } } if (Adriver) db_commit_transaction(Adriver); if (!print_flag->answer) { G_percent(nacats, nacats, 2); db_close_database_shutdown_driver(Adriver); db_free_string(&stmt); G_message(_("%d records updated"), update_ok); if (update_err > 0) G_message(_("%d update errors"), update_err); Vect_set_db_updated(&AIn); } Vect_close(&AIn); G_done_msg(" "); exit(EXIT_SUCCESS); }
int main(int argc, char *argv[]) { const char *name; const char *mapset; long x, y; double dx; RASTER_MAP_TYPE map_type; int i; int from_stdin = FALSE; struct GModule *module; struct { struct Option *map, *fs, *cats, *vals, *raster, *file, *fmt_str, *fmt_coeff; } parm; G_gisinit(argv[0]); module = G_define_module(); G_add_keyword(_("raster")); G_add_keyword(_("category")); module->description = _("Manages category values and labels associated " "with user-specified raster map layers."); parm.map = G_define_standard_option(G_OPT_R_MAP); parm.cats = G_define_standard_option(G_OPT_V_CATS); parm.cats->multiple = YES; parm.cats->guisection = _("Selection"); parm.vals = G_define_option(); parm.vals->key = "vals"; parm.vals->type = TYPE_DOUBLE; parm.vals->multiple = YES; parm.vals->required = NO; parm.vals->label = _("Comma separated value list"); parm.vals->description = _("Example: 1.4,3.8,13"); parm.vals->guisection = _("Selection"); parm.fs = G_define_standard_option(G_OPT_F_SEP); parm.fs->answer = "tab"; parm.raster = G_define_standard_option(G_OPT_R_INPUT); parm.raster->key = "raster"; parm.raster->required = NO; parm.raster->description = _("Raster map from which to copy category table"); parm.raster->guisection = _("Define"); parm.file = G_define_standard_option(G_OPT_F_INPUT); parm.file->key = "rules"; parm.file->required = NO; parm.file->description = _("File containing category label rules (or \"-\" to read from stdin)"); parm.file->guisection = _("Define"); parm.fmt_str = G_define_option(); parm.fmt_str->key = "format"; parm.fmt_str->type = TYPE_STRING; parm.fmt_str->required = NO; parm.fmt_str->label = _("Default label or format string for dynamic labeling"); parm.fmt_str->description = _("Used when no explicit label exists for the category"); parm.fmt_coeff = G_define_option(); parm.fmt_coeff->key = "coefficients"; parm.fmt_coeff->type = TYPE_DOUBLE; parm.fmt_coeff->required = NO; parm.fmt_coeff->key_desc = "mult1,offset1,mult2,offset2"; /* parm.fmt_coeff->answer = "0.0,0.0,0.0,0.0"; */ parm.fmt_coeff->label = _("Dynamic label coefficients"); parm.fmt_coeff->description = _("Two pairs of category multiplier and offsets, for $1 and $2"); if (G_parser(argc, argv)) exit(EXIT_FAILURE); name = parm.map->answer; fs = G_option_to_separator(parm.fs); mapset = G_find_raster2(name, ""); if (mapset == NULL) G_fatal_error(_("Raster map <%s> not found"), name); map_type = Rast_map_type(name, mapset); /* create category labels */ if (parm.raster->answer || parm.file->answer || parm.fmt_str->answer || parm.fmt_coeff->answer) { /* restrict editing to current mapset */ if (strcmp(mapset, G_mapset()) != 0) G_fatal_error(_("Raster map <%s> not found in current mapset"), name); /* use cats from another map */ if (parm.raster->answer) { int fd; const char *cmapset; cmapset = G_find_raster2(parm.raster->answer, ""); if (cmapset == NULL) G_fatal_error(_("Raster map <%s> not found"), parm.raster->answer); fd = Rast_open_old(name, mapset); Rast_init_cats("", &cats); if (0 > Rast_read_cats(parm.raster->answer, cmapset, &cats)) G_fatal_error(_("Unable to read category file of raster map <%s@%s>"), parm.raster->answer, cmapset); Rast_write_cats(name, &cats); G_message(_("Category table for <%s> set from <%s>"), name, parm.raster->answer); Rast_close(fd); } /* load cats from rules file */ if (parm.file->answer) { FILE *fp; char **tokens; int ntokens; char *e1; char *e2; if (strcmp("-", parm.file->answer) == 0) { from_stdin = TRUE; fp = stdin; } else { fp = fopen(parm.file->answer, "r"); if (!fp) G_fatal_error(_("Unable to open file <%s>"), parm.file->answer); } Rast_init_cats("", &cats); for (;;) { char buf[1024]; DCELL d1, d2; int parse_error = 0; if (!G_getl2(buf, sizeof(buf), fp)) break; tokens = G_tokenize(buf, fs); ntokens = G_number_of_tokens(tokens); if (ntokens == 3) { d1 = strtod(tokens[0], &e1); d2 = strtod(tokens[1], &e2); if (*e1 == 0 && *e2 == 0) Rast_set_d_cat(&d1, &d2, tokens[2], &cats); else parse_error = 1; } else if (ntokens == 2) { d1 = strtod(tokens[0], &e1); if (*e1 == 0) Rast_set_d_cat(&d1, &d1, tokens[1], &cats); else parse_error = 1; } else if (!strlen(buf)) continue; else parse_error = 1; if (parse_error) G_fatal_error(_("Incorrect format of input rules. " "Check separators. Invalid line is:\n%s"), buf); } G_free_tokens(tokens); Rast_write_cats(name, &cats); if (!from_stdin) fclose(fp); } /* set dynamic cat rules for cats without explicit labels */ if (parm.fmt_str->answer || parm.fmt_coeff->answer) { char *fmt_str; double m1, a1, m2, a2; /* read existing values */ Rast_init_cats("", &cats); if (0 > Rast_read_cats(name, G_mapset(), &cats)) G_warning(_("Unable to read category file of raster map <%s@%s>"), name, G_mapset()); if (parm.fmt_str->answer) { fmt_str = G_malloc(strlen(parm.fmt_str->answer) > strlen(cats.fmt) ? strlen(parm.fmt_str->answer) + 1 : strlen(cats.fmt) + 1); strcpy(fmt_str, parm.fmt_str->answer); } else { fmt_str = G_malloc(strlen(cats.fmt) + 1); strcpy(fmt_str, cats.fmt); } m1 = cats.m1; a1 = cats.a1; m2 = cats.m2; a2 = cats.a2; if (parm.fmt_coeff->answer) { m1 = atof(parm.fmt_coeff->answers[0]); a1 = atof(parm.fmt_coeff->answers[1]); m2 = atof(parm.fmt_coeff->answers[2]); a2 = atof(parm.fmt_coeff->answers[3]); } Rast_set_cats_fmt(fmt_str, m1, a1, m2, a2, &cats); Rast_write_cats(name, &cats); } Rast_free_cats(&cats); exit(EXIT_SUCCESS); } else { if (Rast_read_cats(name, mapset, &cats) < 0) G_fatal_error(_("Unable to read category file of raster map <%s> in <%s>"), name, mapset); } /* describe the category labels */ /* if no cats requested, use r.describe to get the cats */ if (parm.cats->answer == NULL) { if (map_type == CELL_TYPE) { get_cats(name, mapset); while (next_cat(&x)) print_label(x); exit(EXIT_SUCCESS); } } else { if (map_type != CELL_TYPE) G_warning(_("The map is floating point! Ignoring cats list, using vals list")); else { /* integer map */ for (i = 0; parm.cats->answers[i]; i++) if (!scan_cats(parm.cats->answers[i], &x, &y)) { G_usage(); exit(EXIT_FAILURE); } for (i = 0; parm.cats->answers[i]; i++) { scan_cats(parm.cats->answers[i], &x, &y); while (x <= y) print_label(x++); } exit(EXIT_SUCCESS); } } if (parm.vals->answer == NULL) G_fatal_error(_("vals argument is required for floating point map!")); for (i = 0; parm.vals->answers[i]; i++) if (!scan_vals(parm.vals->answers[i], &dx)) { G_usage(); exit(EXIT_FAILURE); } for (i = 0; parm.vals->answers[i]; i++) { scan_vals(parm.vals->answers[i], &dx); print_d_label(dx); } exit(EXIT_SUCCESS); }
int main(int argc, char *argv[]) { int n, i; int skip; const char *cur_mapset, *mapset; char **ptr; char **tokens; int no_tokens; FILE *fp; char path_buf[GPATH_MAX]; char *path, *fs; int operation, nchoices; char **mapset_name; int nmapsets; struct GModule *module; struct _opt { struct Option *mapset, *op, *fs; struct Flag *print, *list, *dialog; } opt; G_gisinit(argv[0]); module = G_define_module(); G_add_keyword(_("general")); G_add_keyword(_("settings")); G_add_keyword(_("search path")); module->label = _("Modifies/prints the user's current mapset search path."); module->description = _("Affects the user's access to data existing " "under the other mapsets in the current location."); opt.mapset = G_define_standard_option(G_OPT_M_MAPSET); opt.mapset->required = YES; opt.mapset->multiple = YES; opt.mapset->description = _("Name(s) of existing mapset(s) to add/remove or set"); opt.mapset->guisection = _("Search path"); opt.op = G_define_option(); opt.op->key = "operation"; opt.op->type = TYPE_STRING; opt.op->required = YES; opt.op->multiple = NO; opt.op->options = "set,add,remove"; opt.op->description = _("Operation to be performed"); opt.op->guisection = _("Search path"); opt.op->answer = "add"; opt.fs = G_define_standard_option(G_OPT_F_SEP); opt.fs->label = _("Field separator for printing (-l and -p flags)"); opt.fs->answer = "space"; opt.fs->guisection = _("Print"); opt.list = G_define_flag(); opt.list->key = 'l'; opt.list->description = _("List all available mapsets in alphabetical order"); opt.list->guisection = _("Print"); opt.list->suppress_required = YES; opt.print = G_define_flag(); opt.print->key = 'p'; opt.print->description = _("Print mapsets in current search path"); opt.print->guisection = _("Print"); opt.print->suppress_required = YES; opt.dialog = G_define_flag(); opt.dialog->key = 's'; opt.dialog->description = _("Launch mapset selection GUI dialog"); opt.dialog->suppress_required = YES; path = NULL; mapset_name = NULL; nmapsets = nchoices = 0; if (G_parser(argc, argv)) exit(EXIT_FAILURE); operation = OP_UKN; if (opt.mapset->answer && opt.op->answer) { switch(opt.op->answer[0]) { case 's': operation = OP_SET; break; case 'a': operation = OP_ADD; break; case 'r': operation = OP_REM; break; default: G_fatal_error(_("Unknown operation '%s'"), opt.op->answer); break; } } fs = G_option_to_separator(opt.fs); /* list available mapsets */ if (opt.list->answer) { if (opt.print->answer) G_warning(_("Flag -%c ignored"), opt.print->key); if (opt.dialog->answer) G_warning(_("Flag -%c ignored"), opt.dialog->key); if (opt.mapset->answer) G_warning(_("Option <%s> ignored"), opt.mapset->key); mapset_name = get_available_mapsets(&nmapsets); list_available_mapsets((const char **)mapset_name, nmapsets, fs); exit(EXIT_SUCCESS); } if (opt.print->answer) { if (opt.dialog->answer) G_warning(_("Flag -%c ignored"), opt.dialog->key); if (opt.mapset->answer) G_warning(_("Option <%s> ignored"), opt.mapset->key); list_accessible_mapsets(fs); exit(EXIT_SUCCESS); } /* show GUI dialog */ if (opt.dialog->answer) { if (opt.mapset->answer) G_warning(_("Option <%s> ignored"), opt.mapset->key); sprintf(path_buf, "%s/gui/wxpython/modules/mapsets_picker.py", G_gisbase()); G_spawn(getenv("GRASS_PYTHON"), "mapsets_picker.py", path_buf, NULL); exit(EXIT_SUCCESS); } cur_mapset = G_mapset(); /* modify search path */ if (operation == OP_SET) { int cur_found; cur_found = FALSE; for (ptr = opt.mapset->answers; *ptr != NULL; ptr++) { mapset = substitute_mapset(*ptr); if (G__mapset_permissions(mapset) < 0) G_fatal_error(_("Mapset <%s> not found"), mapset); if (strcmp(mapset, cur_mapset) == 0) cur_found = TRUE; nchoices++; append_mapset(&path, mapset); } if (!cur_found) G_warning(_("Current mapset (<%s>) must always included in the search path"), cur_mapset); } else if (operation == OP_ADD) { /* add to existing search path */ const char *oldname; if (path) { G_free(path); path = NULL; } /* read existing mapsets from SEARCH_PATH */ for (n = 0; (oldname = G_get_mapset_name(n)); n++) append_mapset(&path, oldname); /* fetch and add new mapsets from param list */ for (ptr = opt.mapset->answers; *ptr != NULL; ptr++) { mapset = substitute_mapset(*ptr); if (G_is_mapset_in_search_path(mapset)) { G_message(_("Mapset <%s> already in the path"), mapset); continue; } if (G__mapset_permissions(mapset) < 0) G_fatal_error(_("Mapset <%s> not found"), mapset); else G_verbose_message(_("Mapset <%s> added to search path"), mapset); nchoices++; append_mapset(&path, mapset); } } else if (operation == OP_REM) { /* remove from existing search path */ const char *oldname; int found; if (path) { G_free(path); path = NULL; } /* read existing mapsets from SEARCH_PATH */ for (n = 0; (oldname = G_get_mapset_name(n)); n++) { found = FALSE; for (ptr = opt.mapset->answers; *ptr && !found; ptr++) mapset = substitute_mapset(*ptr); if (strcmp(oldname, mapset) == 0) found = TRUE; if (found) { if (strcmp(oldname, cur_mapset) == 0) G_warning(_("Current mapset (<%s>) must always included in the search path"), cur_mapset); else G_verbose_message(_("Mapset <%s> removed from search path"), oldname); continue; } nchoices++; append_mapset(&path, oldname); } } /* stuffem sets nchoices */ if (nchoices == 0) { G_important_message(_("Search path not modified")); if (path) G_free(path); if (nmapsets) { for(nmapsets--; nmapsets >= 0; nmapsets--) G_free(mapset_name[nmapsets]); G_free(mapset_name); } exit(EXIT_SUCCESS); } /* note I'm assuming that mapsets cannot have ' 's in them */ tokens = G_tokenize(path, " "); fp = G_fopen_new("", "SEARCH_PATH"); if (!fp) G_fatal_error(_("Unable to open SEARCH_PATH for write")); /* * make sure current mapset is specified in the list if not add it * to the head of the list */ skip = 0; for (n = 0; n < nchoices; n++) if (strcmp(cur_mapset, tokens[n]) == 0) { skip = 1; break; } if (!skip) { fprintf(fp, "%s\n", cur_mapset); } /* * output the list, removing duplicates */ no_tokens = G_number_of_tokens(tokens); for (n = 0; n < no_tokens; n++) { skip = 0; for (i = n; i < no_tokens; i++) { if (i != n) { if (strcmp(tokens[i], tokens[n]) == 0) skip = 1; } } if (!skip) fprintf(fp, "%s\n", tokens[n]); } fclose(fp); G_free_tokens(tokens); if (path) G_free(path); if (nmapsets) { for(nmapsets--; nmapsets >= 0; nmapsets--) G_free(mapset_name[nmapsets]); G_free(mapset_name); } exit(EXIT_SUCCESS); }
void parse_command_line(int argc, char **argv) { struct Option *driver, *database, *table, *sql, *fs, *vs, *nv, *input, *output; struct Flag *c, *d, *v, *flag_test; struct GModule *module; const char *drv, *db; /* Initialize the GIS calls */ G_gisinit(argv[0]); sql = G_define_standard_option(G_OPT_DB_SQL); sql->guisection = _("Query"); input = G_define_standard_option(G_OPT_F_INPUT); input->required = NO; input->label = _("Name of file containing SQL select statement(s)"); input->description = _("'-' for standard input"); input->guisection = _("Query"); table = G_define_standard_option(G_OPT_DB_TABLE); table->description = _("Name of table to query"); table->guisection = _("Query"); driver = G_define_standard_option(G_OPT_DB_DRIVER); driver->options = db_list_drivers(); if ((drv = db_get_default_driver_name())) driver->answer = (char *) drv; driver->guisection = _("Connection"); database = G_define_standard_option(G_OPT_DB_DATABASE); if ((db = db_get_default_database_name())) database->answer = (char *) db; database->guisection = _("Connection"); fs = G_define_standard_option(G_OPT_F_SEP); fs->guisection = _("Format"); vs = G_define_standard_option(G_OPT_F_SEP); vs->key = "vseparator"; vs->label = _("Vertical record separator (requires -v flag)"); vs->answer = NULL; vs->guisection = _("Format"); nv = G_define_option(); nv->key = "nv"; nv->type = TYPE_STRING; nv->required = NO; nv->description = _("Null value indicator"); nv->guisection = _("Format"); output = G_define_standard_option(G_OPT_F_OUTPUT); output->required = NO; output->description = _("Name for output file (if omitted or \"-\" output to stdout)"); c = G_define_flag(); c->key = 'c'; c->description = _("Do not include column names in output"); c->guisection = _("Format"); d = G_define_flag(); d->key = 'd'; d->description = _("Describe query only (don't run it)"); d->guisection = _("Query"); v = G_define_flag(); v->key = 'v'; v->description = _("Vertical output (instead of horizontal)"); v->guisection = _("Format"); flag_test = G_define_flag(); flag_test->key = 't'; flag_test->description = _("Only test query, do not execute"); flag_test->guisection = _("Query"); /* Set description */ module = G_define_module(); G_add_keyword(_("database")); G_add_keyword(_("attribute table")); G_add_keyword(_("SQL")); module->label = _("Selects data from attribute table."); module->description = _("Performs SQL query statement(s)."); if (G_parser(argc, argv)) exit(EXIT_FAILURE); parms.driver = driver->answer; parms.database = database->answer; parms.table = table->answer; parms.sql = sql->answer; parms.fs = G_option_to_separator(fs); parms.vs = '\0'; if (vs->answer) parms.vs = G_option_to_separator(vs); parms.nv = nv->answer; parms.input = input->answer; parms.output = output->answer; if (!c->answer) parms.c = TRUE; else parms.c = FALSE; parms.d = d->answer; if (!v->answer) parms.h = TRUE; else parms.h = FALSE; parms.test_only = flag_test->answer; if (parms.input && *parms.input == 0) { G_usage(); exit(EXIT_FAILURE); } if (!parms.input && !parms.sql && !parms.table) G_fatal_error(_("You must provide one of these options: <%s>, <%s>, or <%s>"), sql->key, input->key, table->key); }
int main(int argc, char **argv) { struct GModule *module; // struct Option *opt_input, *opt_sep; struct Option *opt_at, *opt_cols, *opt_font, *opt_fontsize, *opt_fontcolor, *opt_title, *opt_tit_font, *opt_tit_fontsize, *opt_sub_font, *opt_sub_fontsize, *opt_bcolor, *opt_bgcolor, *opt_symb_size, *opt_bg_width, *opt_output, *opt_input, *opt_sep; struct Flag *fl_bg; double LL, LT; char *title, *file_name; int bcolor, bgcolor, do_bg; int fontsize, fontcolor, tit_size, sub_size; char *font, *tit_font, *sub_font; int cols, symb_size, bg_width; char *out_file; FILE *source; char buf[BUFFSIZE]; char *sep; size_t nread; /* Initialize the GIS calls */ G_gisinit(argv[0]); module = G_define_module(); G_add_keyword(_("display")); G_add_keyword(_("cartography")); G_add_keyword(_("vector")); G_add_keyword(_("legend")); module->description = _("Displays a vector legend " "in the active graphics frame."); opt_at = G_define_option(); opt_at->key = "at"; opt_at->key_desc = "left,top"; opt_at->type = TYPE_DOUBLE; opt_at->options = "0-100"; opt_at->answer = "10,40"; opt_at->required = NO; opt_at->description = _("Screen position of legend to be drawn (percentage, [0,0] is lower left)"); opt_cols = G_define_option(); opt_cols->key = "columns"; opt_cols->type = TYPE_INTEGER; opt_cols->answer = "1"; opt_cols->required = NO; opt_cols->description = _("Number of legend columns"); opt_cols->guisection = _("Layout"); opt_title = G_define_option(); opt_title->key = "title"; opt_title->type = TYPE_STRING; opt_title->required = NO; opt_title->description = _("Legend title"); opt_title->guisection = _("Title"); opt_symb_size = G_define_option(); opt_symb_size->key = "symbol_size"; opt_symb_size->type = TYPE_INTEGER; opt_symb_size->required = NO; opt_symb_size->description = _("Symbol size"); opt_symb_size->answer = "20"; opt_symb_size->guisection = _("Layout"); opt_bcolor = G_define_standard_option(G_OPT_CN); opt_bcolor->key = "border_color"; opt_bcolor->answer = "black"; opt_bcolor->label = _("Border color"); opt_bcolor->guisection = _("Background"); opt_bgcolor = G_define_standard_option(G_OPT_CN); opt_bgcolor->key = "bgcolor"; opt_bgcolor->answer = "white"; opt_bgcolor->label = _("Background color"); opt_bgcolor->guisection = _("Background"); opt_bg_width = G_define_option(); opt_bg_width->type = TYPE_INTEGER; opt_bg_width->key = "border_width"; opt_bg_width->answer = "2"; opt_bg_width->label = _("Background border width"); opt_bg_width->guisection = _("Background"); opt_font = G_define_option(); opt_font->key = "font"; opt_font->type = TYPE_STRING; opt_font->required = NO; opt_font->description = _("Font name"); opt_font->guisection = _("Font settings"); opt_fontsize = G_define_option(); opt_fontsize->key = "fontsize"; opt_fontsize->type = TYPE_DOUBLE; opt_fontsize->required = NO; opt_fontsize->options = "1-360"; opt_fontsize->label = _("Font size"); opt_fontsize->description = _("Default: 12"); opt_fontsize->guisection = _("Font settings"); opt_tit_font = G_define_option(); opt_tit_font->key = "title_font"; opt_tit_font->type = TYPE_STRING; opt_tit_font->required = NO; opt_tit_font->description = _("Title font name"); opt_tit_font->guisection = _("Font settings"); opt_tit_fontsize = G_define_option(); opt_tit_fontsize->key = "title_fontsize"; opt_tit_fontsize->type = TYPE_DOUBLE; opt_tit_fontsize->required = NO; opt_tit_fontsize->options = "1-360"; opt_tit_fontsize->label = _("Title font size"); opt_tit_fontsize->description = _("Default: 18"); opt_tit_fontsize->guisection = _("Title"); opt_sub_font = G_define_option(); opt_sub_font->key = "sub_font"; opt_sub_font->type = TYPE_STRING; opt_sub_font->required = NO; opt_sub_font->description = _("Subtitle font name"); opt_sub_font->guisection = _("Font settings"); opt_sub_fontsize = G_define_option(); opt_sub_fontsize->key = "sub_fontsize"; opt_sub_fontsize->type = TYPE_DOUBLE; opt_sub_fontsize->required = NO; opt_sub_fontsize->options = "1-360"; opt_sub_fontsize->label = _("Subtitle font size"); opt_sub_fontsize->description = _("Default: 14"); opt_sub_fontsize->guisection = _("Font settings"); opt_fontcolor = G_define_standard_option(G_OPT_C); opt_fontcolor->key = "fontcolor"; opt_fontcolor->answer = "black"; opt_fontcolor->label = _("Font color"); opt_fontcolor->guisection = _("Font settings"); fl_bg = G_define_flag(); fl_bg->key = 'b'; fl_bg->description = _("Display legend background"); fl_bg->guisection = _("Background"); opt_input = G_define_standard_option(G_OPT_F_INPUT); opt_input->label = _("Input legend file"); opt_input->description = _("Path to legend file "); opt_input->required = NO; opt_input->guisection = _("In/Out"); opt_output = G_define_standard_option(G_OPT_F_OUTPUT); opt_output->label = _("Output csv file"); opt_output->description = _("Path to output file or '-' " "for standard output"); opt_output->required = NO; opt_output->guisection = _("In/Out"); opt_sep = G_define_standard_option(G_OPT_F_SEP); opt_sep->guisection = _("In/Out"); /* Check command line */ if (G_parser(argc, argv)) { exit(EXIT_FAILURE); } D_open_driver(); D_setup_unity(0); /* parse and check options and flags */ if (opt_at->answer) { sscanf(opt_at->answers[0], "%lf", &LL); sscanf(opt_at->answers[1], "%lf", <); } else { LL = 10; LT = 40; } if (opt_title->answer) title = opt_title->answer; else title = ""; if (opt_cols->answer) sscanf(opt_cols->answer, "%d", &cols); else cols = 1; sscanf(opt_symb_size->answer, "%d", &symb_size); sscanf(opt_bg_width->answer, "%d", &bg_width); /* Background */ do_bg = fl_bg->answer; bcolor = D_parse_color(opt_bcolor->answer, TRUE); bgcolor = D_parse_color(opt_bgcolor->answer, TRUE); /* Font settings */ if (opt_font->answer) font = opt_font->answer; else font = "sans"; if (opt_fontsize->answer != NULL) sscanf(opt_fontsize->answer, "%d", &fontsize); else fontsize = 14; if (opt_tit_font->answer) tit_font = opt_tit_font->answer; else tit_font = font; if (opt_tit_fontsize->answer) sscanf(opt_tit_fontsize->answer, "%d", &tit_size); else tit_size = fontsize; if (opt_sub_font->answer) sub_font = opt_sub_font->answer; else sub_font = font; if (opt_sub_fontsize->answer) sscanf(opt_sub_fontsize->answer, "%d", &sub_size); else sub_size = fontsize; fontcolor = D_parse_color(opt_fontcolor->answer, FALSE); /*default color: black */ /* I/O */ sep = G_option_to_separator(opt_sep); if (opt_input->answer) { file_name = opt_input->answer; if (!file_name) G_fatal_error(_("Unable to open input file <%s>"), file_name); } else { file_name = getenv("GRASS_LEGEND_FILE"); if (!file_name) G_fatal_error("No legend file defined."); } if (opt_output->answer) { if (strcmp(opt_output->answer,"-") == 0) { source = fopen(file_name, "r"); if (!source) G_fatal_error(_("Unable to open input file <%s>"), file_name); while ((nread = fread(buf, 1, sizeof(buf), source))) fwrite(buf, 1, nread, stdout); fclose(source); } else { out_file = opt_output->answer; G_copy_file(file_name, out_file); } } /* Pre-calculate the layout */ if (do_bg) draw(file_name, LL, LT, title, cols, bgcolor, bcolor, bg_width, 1, tit_font, tit_size, sub_font, sub_size, font, fontsize, fontcolor, symb_size, sep); /* Draw legend */ draw(file_name, LL, LT, title, cols, bgcolor, bcolor, bg_width, 0, tit_font, tit_size, sub_font, sub_size, font, fontsize, fontcolor, symb_size, sep); D_close_driver(); exit(EXIT_SUCCESS); }