/* ---------------------------------------------------------------------- */ void parse_args(int argc, char *argv[]) { /* input elevation grid */ struct Option *input_elev; input_elev = G_define_standard_option(G_OPT_R_ELEV); /* output filled elevation grid */ struct Option *output_elev; output_elev = G_define_standard_option(G_OPT_R_OUTPUT); output_elev->key = "filled"; output_elev->description= _("Name for output filled (flooded) elevation raster map"); /* output direction grid */ struct Option *output_dir; output_dir = G_define_standard_option(G_OPT_R_OUTPUT); output_dir->key = "direction"; output_dir->description= _("Name for output flow direction raster map"); /* output sinkwatershed grid */ struct Option *output_watershed; output_watershed = G_define_standard_option(G_OPT_R_OUTPUT); output_watershed->key = "swatershed"; output_watershed->description= _("Name for output sink-watershed raster map"); /* output flow accumulation grid */ struct Option *output_accu; output_accu = G_define_standard_option(G_OPT_R_OUTPUT); output_accu->key = "accumulation"; output_accu->description= _("Name for output flow accumulation raster map"); #ifdef OUTPUT_TCI struct Option *output_tci; output_tci = G_define_standard_option(G_OPT_R_OUTPUT); output_tci->key = "tci"; output_tci->description= _("Name for output topographic convergence index (tci) raster map"); #endif /* MFD/SFD flag */ struct Flag *sfd_flag; sfd_flag = G_define_flag() ; sfd_flag->key = 's'; sfd_flag->description= _("SFD (D8) flow (default is MFD)"); /* D8CUT value*/ struct Option *d8cut; d8cut = G_define_option(); d8cut->key = "d8cut"; d8cut->type = TYPE_DOUBLE; d8cut->required = NO; d8cut->answer = G_store("infinity"); /* default value */ d8cut->label = _("Routing using SFD (D8) direction"); d8cut->description = _("If flow accumulation is larger than this value it is routed using " "SFD (D8) direction (meaningfull only for MFD flow)"); /* main memory */ struct Option *mem; mem = G_define_option() ; mem->key = "memory"; mem->type = TYPE_INTEGER; mem->required = NO; mem->answer = G_store("300"); /* 300MB default value */ mem->description = _("Maximum runtime memory size (in MB)"); /* temporary STREAM path */ struct Option *streamdir; streamdir = G_define_option() ; streamdir->key = "stream_dir"; streamdir->type = TYPE_STRING; streamdir->required = NO; #ifdef __MINGW32__ streamdir->answer = G_convert_dirseps_from_host(G_store(getenv("TEMP"))); #else streamdir->answer = G_store("/var/tmp/"); #endif streamdir->description= _("Directory to hold temporary files (they can be large)"); /* stats file */ struct Option *stats_opt; stats_opt = G_define_option() ; stats_opt->key = "stats"; stats_opt->type = TYPE_STRING; stats_opt->required = NO; stats_opt->description= _("Name of file containing runtime statistics"); stats_opt->answer = G_store("stats.out"); if (G_parser(argc, argv)) { exit (EXIT_FAILURE); } /* ************************* */ assert(opt); opt->elev_grid = input_elev->answer; opt->filled_grid = output_elev->answer; opt->dir_grid = output_dir->answer; opt->watershed_grid = output_watershed->answer; opt->flowaccu_grid = output_accu->answer; #ifdef OUTPUT_TCI opt->tci_grid = output_tci->answer; #endif opt->d8 = sfd_flag->answer; if (strcmp(d8cut->answer, "infinity") == 0) { opt->d8cut = MAX_ACCU; } else { opt->d8cut = atof(d8cut->answer); } opt->mem = atoi(mem->answer); opt->streamdir = streamdir->answer; opt->verbose = G_verbose() == G_verbose_max(); opt->stats = stats_opt->answer; /* somebody should delete the options */ }
int main(int argc, char *argv[]) { int i, type, stat; int day, yr, Out_proj; int out_zone = 0; int overwrite; /* overwrite output map */ const char *mapset; const char *omap_name, *map_name, *iset_name, *iloc_name; struct pj_info info_in; struct pj_info info_out; const char *gbase; char date[40], mon[4]; struct GModule *module; struct Option *omapopt, *mapopt, *isetopt, *ilocopt, *ibaseopt, *smax; struct Key_Value *in_proj_keys, *in_unit_keys; struct Key_Value *out_proj_keys, *out_unit_keys; struct line_pnts *Points, *Points2; struct line_cats *Cats; struct Map_info Map; struct Map_info Out_Map; struct bound_box src_box, tgt_box; int nowrap = 0, recommend_nowrap = 0; double lmax; struct { struct Flag *list; /* list files in source location */ struct Flag *transformz; /* treat z as ellipsoidal height */ struct Flag *wrap; /* latlon output: wrap to 0,360 */ struct Flag *no_topol; /* do not build topology */ } flag; G_gisinit(argv[0]); module = G_define_module(); G_add_keyword(_("vector")); G_add_keyword(_("projection")); G_add_keyword(_("transformation")); G_add_keyword(_("import")); module->description = _("Re-projects a vector map from one location to the current location."); /* set up the options and flags for the command line parser */ ilocopt = G_define_standard_option(G_OPT_M_LOCATION); ilocopt->required = YES; ilocopt->label = _("Location containing input vector map"); ilocopt->guisection = _("Source"); isetopt = G_define_standard_option(G_OPT_M_MAPSET); isetopt->label = _("Mapset containing input vector map"); isetopt->description = _("Default: name of current mapset"); isetopt->guisection = _("Source"); mapopt = G_define_standard_option(G_OPT_V_INPUT); mapopt->required = NO; mapopt->label = _("Name of input vector map to re-project"); mapopt->description = NULL; mapopt->guisection = _("Source"); ibaseopt = G_define_standard_option(G_OPT_M_DBASE); ibaseopt->label = _("Path to GRASS database of input location"); smax = G_define_option(); smax->key = "smax"; smax->type = TYPE_DOUBLE; smax->required = NO; smax->answer = "10000"; smax->label = _("Maximum segment length in meters in output vector map"); smax->description = _("Increases accuracy of reprojected shapes, disable with smax=0"); smax->guisection = _("Target"); omapopt = G_define_standard_option(G_OPT_V_OUTPUT); omapopt->required = NO; omapopt->description = _("Name for output vector map (default: input)"); omapopt->guisection = _("Target"); flag.list = G_define_flag(); flag.list->key = 'l'; flag.list->description = _("List vector maps in input mapset and exit"); flag.transformz = G_define_flag(); flag.transformz->key = 'z'; flag.transformz->description = _("3D vector maps only"); flag.transformz->label = _("Assume z coordinate is ellipsoidal height and " "transform if possible"); flag.transformz->guisection = _("Target"); flag.wrap = G_define_flag(); flag.wrap->key = 'w'; flag.wrap->description = _("Latlon output only, default is -180,180"); flag.wrap->label = _("Disable wrapping to -180,180 for latlon output"); flag.transformz->guisection = _("Target"); flag.no_topol = G_define_flag(); flag.no_topol->key = 'b'; flag.no_topol->label = _("Do not build vector topology"); flag.no_topol->description = _("Recommended for massive point projection"); /* The parser checks if the map already exists in current mapset, we switch out the check and do it in the module after the parser */ overwrite = G_check_overwrite(argc, argv); if (G_parser(argc, argv)) exit(EXIT_FAILURE); /* start checking options and flags */ /* set input vector map name and mapset */ map_name = mapopt->answer; if (omapopt->answer) omap_name = omapopt->answer; else omap_name = map_name; if (omap_name && !flag.list->answer && !overwrite && G_find_vector2(omap_name, G_mapset())) G_fatal_error(_("option <%s>: <%s> exists. To overwrite, use the --overwrite flag"), omapopt->key, omap_name); if (isetopt->answer) iset_name = isetopt->answer; else iset_name = G_store(G_mapset()); iloc_name = ilocopt->answer; if (ibaseopt->answer) gbase = ibaseopt->answer; else gbase = G_store(G_gisdbase()); if (!ibaseopt->answer && strcmp(iloc_name, G_location()) == 0) G_fatal_error(_("Input and output locations can not be the same")); lmax = atof(smax->answer); if (lmax < 0) lmax = 0; Out_proj = G_projection(); if (Out_proj == PROJECTION_LL && flag.wrap->answer) nowrap = 1; G_begin_distance_calculations(); /* Change the location here and then come back */ select_target_env(); G_setenv_nogisrc("GISDBASE", gbase); G_setenv_nogisrc("LOCATION_NAME", iloc_name); stat = G_mapset_permissions(iset_name); if (stat >= 0) { /* yes, we can access the mapset */ /* if requested, list the vector maps in source location - MN 5/2001 */ if (flag.list->answer) { int i; char **list; G_verbose_message(_("Checking location <%s> mapset <%s>"), iloc_name, iset_name); list = G_list(G_ELEMENT_VECTOR, G_getenv_nofatal("GISDBASE"), G_getenv_nofatal("LOCATION_NAME"), iset_name); if (list[0]) { for (i = 0; list[i]; i++) { fprintf(stdout, "%s\n", list[i]); } fflush(stdout); } else { G_important_message(_("No vector maps found")); } exit(EXIT_SUCCESS); /* leave v.proj after listing */ } if (mapopt->answer == NULL) { G_fatal_error(_("Required parameter <%s> not set"), mapopt->key); } G_setenv_nogisrc("MAPSET", iset_name); /* Make sure map is available */ mapset = G_find_vector2(map_name, iset_name); if (mapset == NULL) G_fatal_error(_("Vector map <%s> in location <%s> mapset <%s> not found"), map_name, iloc_name, iset_name); /*** Get projection info for input mapset ***/ in_proj_keys = G_get_projinfo(); if (in_proj_keys == NULL) exit(EXIT_FAILURE); /* apparently the +over switch must be set in the input projection, * not the output latlon projection */ if (Out_proj == PROJECTION_LL && nowrap == 1) G_set_key_value("+over", "defined", in_proj_keys); in_unit_keys = G_get_projunits(); if (in_unit_keys == NULL) exit(EXIT_FAILURE); if (pj_get_kv(&info_in, in_proj_keys, in_unit_keys) < 0) exit(EXIT_FAILURE); Vect_set_open_level(1); G_debug(1, "Open old: location: %s mapset : %s", G_location_path(), G_mapset()); if (Vect_open_old(&Map, map_name, mapset) < 0) G_fatal_error(_("Unable to open vector map <%s>"), map_name); } else if (stat < 0) { /* allow 0 (i.e. denied permission) */ /* need to be able to read from others */ if (stat == 0) G_fatal_error(_("Mapset <%s> in input location <%s> - permission denied"), iset_name, iloc_name); else G_fatal_error(_("Mapset <%s> in input location <%s> not found"), iset_name, iloc_name); } select_current_env(); /****** get the output projection parameters ******/ out_proj_keys = G_get_projinfo(); if (out_proj_keys == NULL) exit(EXIT_FAILURE); out_unit_keys = G_get_projunits(); if (out_unit_keys == NULL) exit(EXIT_FAILURE); if (pj_get_kv(&info_out, out_proj_keys, out_unit_keys) < 0) exit(EXIT_FAILURE); G_free_key_value(in_proj_keys); G_free_key_value(in_unit_keys); G_free_key_value(out_proj_keys); G_free_key_value(out_unit_keys); if (G_verbose() == G_verbose_max()) { pj_print_proj_params(&info_in, &info_out); } /* Initialize the Point / Cat structure */ Points = Vect_new_line_struct(); Points2 = Vect_new_line_struct(); Cats = Vect_new_cats_struct(); /* test if latlon wrapping to -180,180 should be disabled */ if (Out_proj == PROJECTION_LL && nowrap == 0) { int first = 1, counter = 0; double x, y; /* Cycle through all lines */ Vect_rewind(&Map); while (1) { type = Vect_read_next_line(&Map, Points, Cats); /* read line */ if (type == 0) continue; /* Dead */ if (type == -1) G_fatal_error(_("Reading input vector map")); if (type == -2) break; if (first && Points->n_points > 0) { first = 0; src_box.E = src_box.W = Points->x[0]; src_box.N = src_box.S = Points->y[0]; src_box.T = src_box.B = Points->z[0]; } for (i = 0; i < Points->n_points; i++) { if (src_box.E < Points->x[i]) src_box.E = Points->x[i]; if (src_box.W > Points->x[i]) src_box.W = Points->x[i]; if (src_box.N < Points->y[i]) src_box.N = Points->y[i]; if (src_box.S > Points->y[i]) src_box.S = Points->y[i]; } counter++; } if (counter == 0) { G_warning(_("Input vector map <%s> is empty"), omap_name); exit(EXIT_SUCCESS); } /* NW corner */ x = src_box.W; y = src_box.N; if (pj_do_transform(1, &x, &y, NULL, &info_in, &info_out) < 0) { G_fatal_error(_("Error in pj_do_transform")); } tgt_box.E = x; tgt_box.W = x; tgt_box.N = y; tgt_box.S = y; /* SW corner */ x = src_box.W; y = src_box.S; if (pj_do_transform(1, &x, &y, NULL, &info_in, &info_out) < 0) { G_fatal_error(_("Error in pj_do_transform")); } if (tgt_box.W > x) tgt_box.W = x; if (tgt_box.E < x) tgt_box.E = x; if (tgt_box.N < y) tgt_box.N = y; if (tgt_box.S > y) tgt_box.S = y; /* NE corner */ x = src_box.E; y = src_box.N; if (pj_do_transform(1, &x, &y, NULL, &info_in, &info_out) < 0) { G_fatal_error(_("Error in pj_do_transform")); } if (tgt_box.W > x) { tgt_box.E = x + 360; recommend_nowrap = 1; } if (tgt_box.N < y) tgt_box.N = y; if (tgt_box.S > y) tgt_box.S = y; /* SE corner */ x = src_box.E; y = src_box.S; if (pj_do_transform(1, &x, &y, NULL, &info_in, &info_out) < 0) { G_fatal_error(_("Error in pj_do_transform")); } if (tgt_box.W > x) { if (tgt_box.E < x + 360) tgt_box.E = x + 360; recommend_nowrap = 1; } if (tgt_box.N < y) tgt_box.N = y; if (tgt_box.S > y) tgt_box.S = y; } G_debug(1, "Open new: location: %s mapset : %s", G_location_path(), G_mapset()); if (Vect_open_new(&Out_Map, omap_name, Vect_is_3d(&Map)) < 0) G_fatal_error(_("Unable to create vector map <%s>"), omap_name); Vect_set_error_handler_io(NULL, &Out_Map); /* register standard i/o error handler */ Vect_copy_head_data(&Map, &Out_Map); Vect_hist_copy(&Map, &Out_Map); Vect_hist_command(&Out_Map); out_zone = info_out.zone; Vect_set_zone(&Out_Map, out_zone); /* Read and write header info */ sprintf(date, "%s", G_date()); sscanf(date, "%*s%s%d%*s%d", mon, &day, &yr); if (yr < 2000) yr = yr - 1900; else yr = yr - 2000; sprintf(date, "%s %d %d", mon, day, yr); Vect_set_date(&Out_Map, date); /* line densification works only with vector topology */ if (Map.format != GV_FORMAT_NATIVE) lmax = 0; /* Cycle through all lines */ Vect_rewind(&Map); i = 0; G_message(_("Reprojecting primitives ...")); while (TRUE) { ++i; G_progress(i, 1e3); type = Vect_read_next_line(&Map, Points, Cats); /* read line */ if (type == 0) continue; /* Dead */ if (type == -1) G_fatal_error(_("Reading input vector map")); if (type == -2) break; Vect_line_prune(Points); if (lmax > 0 && (type & GV_LINES) && Points->n_points > 1) { double x1, y1, z1, x2, y2, z2; double dx, dy, dz; double l; int i, n; Vect_reset_line(Points2); for (i = 0; i < Points->n_points - 1; i++) { x1 = Points->x[i]; y1 = Points->y[i]; z1 = Points->z[i]; n = i + 1; x2 = Points->x[n]; y2 = Points->y[n]; z2 = Points->z[n]; dx = x2 - x1; dy = y2 - y1; dz = z2 - z1; if (pj_do_transform(1, &x1, &y1, flag.transformz->answer ? &z1 : NULL, &info_in, &info_out) < 0) { G_fatal_error(_("Unable to re-project vector map <%s> from <%s>"), Vect_get_full_name(&Map), ilocopt->answer); } if (pj_do_transform(1, &x2, &y2, flag.transformz->answer ? &z2 : NULL, &info_in, &info_out) < 0) { G_fatal_error(_("Unable to re-project vector map <%s> from <%s>"), Vect_get_full_name(&Map), ilocopt->answer); } Vect_append_point(Points2, x1, y1, z1); l = G_distance(x1, y1, x2, y2); if (l > lmax) { int j; double x, y, z; x1 = Points->x[i]; y1 = Points->y[i]; z1 = Points->z[i]; n = ceil(l / lmax); for (j = 1; j < n; j++) { x = x1 + dx * j / n; y = y1 + dy * j / n; z = z1 + dz * j / n; if (pj_do_transform(1, &x, &y, flag.transformz->answer ? &z : NULL, &info_in, &info_out) < 0) { G_fatal_error(_("Unable to re-project vector map <%s> from <%s>"), Vect_get_full_name(&Map), ilocopt->answer); } Vect_append_point(Points2, x, y, z); } } } Vect_append_point(Points2, x2, y2, z2); Vect_write_line(&Out_Map, type, Points2, Cats); /* write line */ } else { if (pj_do_transform(Points->n_points, Points->x, Points->y, flag.transformz->answer ? Points->z : NULL, &info_in, &info_out) < 0) { G_fatal_error(_("Unable to re-project vector map <%s> from <%s>"), Vect_get_full_name(&Map), ilocopt->answer); } Vect_write_line(&Out_Map, type, Points, Cats); /* write line */ } } /* end lines section */ G_progress(1, 1); /* Copy tables */ if (Vect_copy_tables(&Map, &Out_Map, 0)) G_warning(_("Failed to copy attribute table to output map")); Vect_close(&Map); if (!flag.no_topol->answer) Vect_build(&Out_Map); Vect_close(&Out_Map); if (recommend_nowrap) G_important_message(_("Try to disable wrapping to -180,180 " "if topological errors occurred")); exit(EXIT_SUCCESS); }
static void read_png(void) { unsigned char sig_buf[8]; png_bytep png_buffer; png_bytep *png_rows; int linesize; struct Cell_head cellhd; unsigned int y, c; png_color_8p sig_bit; int sbit, interlace; FILE *ifp; /* initialize input stream and PNG library */ ifp = fopen(input, "rb"); if (!ifp) G_fatal_error(_("Unable to open PNG file '%s'"), input); if (fread(sig_buf, sizeof(sig_buf), 1, ifp) != 1) G_fatal_error(_("Input file empty or too short")); if (png_sig_cmp(sig_buf, 0, sizeof(sig_buf)) != 0) G_fatal_error(_("Input file not a PNG file")); png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); if (!png_ptr) G_fatal_error(_("Unable to allocate PNG structure")); info_ptr = png_create_info_struct(png_ptr); if (!info_ptr) G_fatal_error(_("Unable to allocate PNG structure")); if (setjmp(png_jmpbuf(png_ptr))) G_fatal_error(_("PNG error")); png_init_io(png_ptr, ifp); png_set_sig_bytes(png_ptr, sizeof(sig_buf)); png_read_info(png_ptr, info_ptr); png_get_IHDR(png_ptr, info_ptr, &width, &height, &bit_depth, &color_type, &interlace_type, &compression_type, &filter_type); if (Header || G_verbose() == G_verbose_max()) print_header(); if (Header) { fclose(ifp); exit(0); } /* read image parameters and set up data conversions */ if (png_get_bit_depth(png_ptr, info_ptr) < 8) png_set_packing(png_ptr); sbit = png_get_sBIT(png_ptr, info_ptr, &sig_bit); if (sbit) png_set_shift(png_ptr, sig_bit); if (!png_get_gAMA(png_ptr, info_ptr, &f_gamma)) f_gamma = 0.0; if (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS)) png_set_tRNS_to_alpha(png_ptr); if (Float && color_type == PNG_COLOR_TYPE_PALETTE) png_set_palette_to_rgb(png_ptr); png_read_update_info(png_ptr, info_ptr); interlace = (interlace_type != PNG_INTERLACE_NONE); ialpha = (int) (alpha * channels[C_A].maxval); t_gamma = (f_gamma != 0.0 && d_gamma != 0.0) ? f_gamma * d_gamma : 1.0; /* allocate input buffer */ linesize = png_get_rowbytes(png_ptr, info_ptr); png_buffer = G_malloc(interlace ? height * linesize : linesize); if (interlace) { png_rows = G_malloc(height * sizeof(png_bytep)); for (y = 0; y < height; y++) png_rows[y] = png_buffer + y * linesize; } /* initialize cell header */ Rast_get_window(&cellhd); cellhd.rows = height; cellhd.cols = width; cellhd.north = cellhd.rows; cellhd.south = 0.0; cellhd.east = cellhd.cols; cellhd.west = 0.0; cellhd.ns_res = 1; cellhd.ew_res = 1; Rast_set_window(&cellhd); /* initialize channel information */ switch (color_type) { case PNG_COLOR_TYPE_GRAY: init_channel(&channels[C_Y]); break; case PNG_COLOR_TYPE_GRAY_ALPHA: init_channel(&channels[C_Y]); init_channel(&channels[C_A]); break; case PNG_COLOR_TYPE_PALETTE: init_channel(&channels[C_P]); break; case PNG_COLOR_TYPE_RGB: init_channel(&channels[C_R]); init_channel(&channels[C_G]); init_channel(&channels[C_B]); break; case PNG_COLOR_TYPE_RGB_ALPHA: init_channel(&channels[C_R]); init_channel(&channels[C_G]); init_channel(&channels[C_B]); init_channel(&channels[C_A]); break; } if (sbit) { channels[C_R].maxval = (1 << sig_bit->red ) - 1; channels[C_G].maxval = (1 << sig_bit->green) - 1; channels[C_B].maxval = (1 << sig_bit->blue ) - 1; channels[C_Y].maxval = (1 << sig_bit->gray ) - 1; channels[C_A].maxval = (1 << sig_bit->alpha) - 1; } else { channels[C_R].maxval = (1 << bit_depth) - 1; channels[C_G].maxval = (1 << bit_depth) - 1; channels[C_B].maxval = (1 << bit_depth) - 1; channels[C_Y].maxval = (1 << bit_depth) - 1; channels[C_A].maxval = (1 << bit_depth) - 1; } /* read image and write raster layers */ if (interlace) png_read_image(png_ptr, png_rows); for (y = 0; y < height; y++) { png_bytep p; if (interlace) p = png_rows[y]; else { png_read_row(png_ptr, png_buffer, NULL); p = png_buffer; } if (Float) write_row_float(p); else write_row_int(p); } png_read_end(png_ptr, NULL); fclose(ifp); /* close output files */ for (c = 0; c < 6; c++) { channel *ch = &channels[c]; if (!ch->active) continue; Rast_close(ch->fd); if (Float) G_free(ch->fbuf); else G_free(ch->buf); } /* write title and color table */ G_verbose_message(_("Creating support files for <%s>..."), output); for (c = 0; c < 6; c++) { channel *ch = &channels[c]; if (!ch->active) continue; if (title && *title) Rast_put_cell_title(ch->name, title); if (Float) write_colors_float(c); else write_colors_int(c); } G_free(png_buffer); if (interlace) G_free(png_rows); png_destroy_read_struct(&png_ptr, &info_ptr, NULL); }