void print_proj4(int dontprettify) { struct pj_info pjinfo; char *proj4, *proj4mod, *i; const char *unfact; if (check_xy(FALSE)) return; if (pj_get_kv(&pjinfo, projinfo, projunits) == -1) G_fatal_error(_("Unable to convert projection information to PROJ.4 format")); proj4 = pj_get_def(pjinfo.pj, 0); pj_free(pjinfo.pj); /* GRASS-style PROJ.4 strings don't include a unit factor as this is * handled separately in GRASS - must include it here though */ unfact = G_find_key_value("meters", projunits); if (unfact != NULL && (strcmp(pjinfo.proj, "ll") != 0)) G_asprintf(&proj4mod, "%s +to_meter=%s", proj4, unfact); else proj4mod = G_store(proj4); pj_dalloc(proj4); for (i = proj4mod; *i; i++) { /* Don't print the first space */ if (i == proj4mod && *i == ' ') continue; if (*i == ' ' && *(i+1) == '+' && !(dontprettify)) fputc('\n', stdout); else fputc(*i, stdout); } fputc('\n', stdout); G_free(proj4mod); return; }
int main(int argc, char **argv) { char *mapname, /* ptr to name of output layer */ *setname, /* ptr to name of input mapset */ *ipolname; /* name of interpolation method */ int fdi, /* input map file descriptor */ fdo, /* output map file descriptor */ method, /* position of method in table */ permissions, /* mapset permissions */ cell_type, /* output celltype */ cell_size, /* size of a cell in bytes */ row, col, /* counters */ irows, icols, /* original rows, cols */ orows, ocols, have_colors, /* Input map has a colour table */ overwrite, /* Overwrite */ curr_proj; /* output projection (see gis.h) */ void *obuffer, /* buffer that holds one output row */ *obufptr; /* column ptr in output buffer */ struct cache *ibuffer; /* buffer that holds the input map */ func interpolate; /* interpolation routine */ double xcoord1, xcoord2, /* temporary x coordinates */ ycoord1, ycoord2, /* temporary y coordinates */ col_idx, /* column index in input matrix */ row_idx, /* row index in input matrix */ onorth, osouth, /* save original border coords */ oeast, owest, inorth, isouth, ieast, iwest; char north_str[30], south_str[30], east_str[30], west_str[30]; struct Colors colr; /* Input map colour table */ struct History history; struct pj_info iproj, /* input map proj parameters */ oproj; /* output map proj parameters */ struct Key_Value *in_proj_info, /* projection information of */ *in_unit_info, /* input and output mapsets */ *out_proj_info, *out_unit_info; struct GModule *module; struct Flag *list, /* list files in source location */ *nocrop, /* don't crop output map */ *print_bounds, /* print output bounds and exit */ *gprint_bounds; /* same but print shell style */ struct Option *imapset, /* name of input mapset */ *inmap, /* name of input layer */ *inlocation, /* name of input location */ *outmap, /* name of output layer */ *indbase, /* name of input database */ *interpol, /* interpolation method: nearest neighbor, bilinear, cubic */ *memory, /* amount of memory for cache */ *res; /* resolution of target map */ struct Cell_head incellhd, /* cell header of input map */ outcellhd; /* and output map */ G_gisinit(argv[0]); module = G_define_module(); G_add_keyword(_("raster")); G_add_keyword(_("projection")); G_add_keyword(_("transformation")); module->description = _("Re-projects a raster map from given location to the current location."); inmap = G_define_standard_option(G_OPT_R_INPUT); inmap->description = _("Name of input raster map to re-project"); inmap->required = NO; inmap->guisection = _("Source"); inlocation = G_define_option(); inlocation->key = "location"; inlocation->type = TYPE_STRING; inlocation->required = YES; inlocation->description = _("Location containing input raster map"); inlocation->gisprompt = "old,location,location"; inlocation->key_desc = "name"; imapset = G_define_standard_option(G_OPT_M_MAPSET); imapset->label = _("Mapset containing input raster map"); imapset->description = _("default: name of current mapset"); imapset->guisection = _("Source"); indbase = G_define_option(); indbase->key = "dbase"; indbase->type = TYPE_STRING; indbase->required = NO; indbase->description = _("Path to GRASS database of input location"); indbase->gisprompt = "old,dbase,dbase"; indbase->key_desc = "path"; indbase->guisection = _("Source"); outmap = G_define_standard_option(G_OPT_R_OUTPUT); outmap->required = NO; outmap->description = _("Name for output raster map (default: same as 'input')"); outmap->guisection = _("Target"); ipolname = make_ipol_list(); interpol = G_define_option(); interpol->key = "method"; interpol->type = TYPE_STRING; interpol->required = NO; interpol->answer = "nearest"; interpol->options = ipolname; interpol->description = _("Interpolation method to use"); interpol->guisection = _("Target"); interpol->descriptions = make_ipol_desc(); memory = G_define_option(); memory->key = "memory"; memory->type = TYPE_INTEGER; memory->required = NO; memory->description = _("Cache size (MiB)"); res = G_define_option(); res->key = "resolution"; res->type = TYPE_DOUBLE; res->required = NO; res->description = _("Resolution of output raster map"); res->guisection = _("Target"); list = G_define_flag(); list->key = 'l'; list->description = _("List raster maps in input location and exit"); nocrop = G_define_flag(); nocrop->key = 'n'; nocrop->description = _("Do not perform region cropping optimization"); print_bounds = G_define_flag(); print_bounds->key = 'p'; print_bounds->description = _("Print input map's bounds in the current projection and exit"); print_bounds->guisection = _("Target"); gprint_bounds = G_define_flag(); gprint_bounds->key = 'g'; gprint_bounds->description = _("Print input map's bounds in the current projection and exit (shell style)"); gprint_bounds->guisection = _("Target"); /* 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); /* get the method */ for (method = 0; (ipolname = menu[method].name); method++) if (strcmp(ipolname, interpol->answer) == 0) break; if (!ipolname) G_fatal_error(_("<%s=%s> unknown %s"), interpol->key, interpol->answer, interpol->key); interpolate = menu[method].method; mapname = outmap->answer ? outmap->answer : inmap->answer; if (mapname && !list->answer && !overwrite && G_find_raster(mapname, G_mapset())) G_fatal_error(_("option <%s>: <%s> exists."), "output", mapname); setname = imapset->answer ? imapset->answer : G_store(G_mapset()); if (strcmp(inlocation->answer, G_location()) == 0 && (!indbase->answer || strcmp(indbase->answer, G_gisdbase()) == 0)) #if 0 G_fatal_error(_("Input and output locations can not be the same")); #else G_warning(_("Input and output locations are the same")); #endif G_get_window(&outcellhd); if(gprint_bounds->answer && !print_bounds->answer) print_bounds->answer = gprint_bounds->answer; curr_proj = G_projection(); /* Get projection info for output mapset */ if ((out_proj_info = G_get_projinfo()) == NULL) G_fatal_error(_("Unable to get projection info of output raster map")); if ((out_unit_info = G_get_projunits()) == NULL) G_fatal_error(_("Unable to get projection units of output raster map")); if (pj_get_kv(&oproj, out_proj_info, out_unit_info) < 0) G_fatal_error(_("Unable to get projection key values of output raster map")); /* Change the location */ G__create_alt_env(); G__setenv("GISDBASE", indbase->answer ? indbase->answer : G_gisdbase()); G__setenv("LOCATION_NAME", inlocation->answer); permissions = G__mapset_permissions(setname); if (permissions < 0) /* can't access mapset */ G_fatal_error(_("Mapset <%s> in input location <%s> - %s"), setname, inlocation->answer, permissions == 0 ? _("permission denied") : _("not found")); /* if requested, list the raster maps in source location - MN 5/2001 */ if (list->answer) { int i; char **list; G_verbose_message(_("Checking location <%s> mapset <%s>"), inlocation->answer, setname); list = G_list(G_ELEMENT_RASTER, G__getenv("GISDBASE"), G__getenv("LOCATION_NAME"), setname); for (i = 0; list[i]; i++) { fprintf(stdout, "%s\n", list[i]); } fflush(stdout); exit(EXIT_SUCCESS); /* leave r.proj after listing */ } if (!inmap->answer) G_fatal_error(_("Required parameter <%s> not set"), inmap->key); if (!G_find_raster(inmap->answer, setname)) G_fatal_error(_("Raster map <%s> in location <%s> in mapset <%s> not found"), inmap->answer, inlocation->answer, setname); /* Read input map colour table */ have_colors = Rast_read_colors(inmap->answer, setname, &colr); /* Get projection info for input mapset */ if ((in_proj_info = G_get_projinfo()) == NULL) G_fatal_error(_("Unable to get projection info of input map")); if ((in_unit_info = G_get_projunits()) == NULL) G_fatal_error(_("Unable to get projection units of input map")); if (pj_get_kv(&iproj, in_proj_info, in_unit_info) < 0) G_fatal_error(_("Unable to get projection key values of input map")); G_free_key_value(in_proj_info); G_free_key_value(in_unit_info); G_free_key_value(out_proj_info); G_free_key_value(out_unit_info); if (G_verbose() > G_verbose_std()) pj_print_proj_params(&iproj, &oproj); /* this call causes r.proj to read the entire map into memeory */ Rast_get_cellhd(inmap->answer, setname, &incellhd); Rast_set_input_window(&incellhd); if (G_projection() == PROJECTION_XY) G_fatal_error(_("Unable to work with unprojected data (xy location)")); /* Save default borders so we can show them later */ inorth = incellhd.north; isouth = incellhd.south; ieast = incellhd.east; iwest = incellhd.west; irows = incellhd.rows; icols = incellhd.cols; onorth = outcellhd.north; osouth = outcellhd.south; oeast = outcellhd.east; owest = outcellhd.west; orows = outcellhd.rows; ocols = outcellhd.cols; if (print_bounds->answer) { G_message(_("Input map <%s@%s> in location <%s>:"), inmap->answer, setname, inlocation->answer); if (pj_do_proj(&iwest, &isouth, &iproj, &oproj) < 0) G_fatal_error(_("Error in pj_do_proj (projection of input coordinate pair)")); if (pj_do_proj(&ieast, &inorth, &iproj, &oproj) < 0) G_fatal_error(_("Error in pj_do_proj (projection of input coordinate pair)")); G_format_northing(inorth, north_str, curr_proj); G_format_northing(isouth, south_str, curr_proj); G_format_easting(ieast, east_str, curr_proj); G_format_easting(iwest, west_str, curr_proj); if(gprint_bounds->answer) { fprintf(stdout, "n=%s s=%s w=%s e=%s rows=%d cols=%d\n", north_str, south_str, west_str, east_str, irows, icols); } else { fprintf(stdout, "Source cols: %d\n", icols); fprintf(stdout, "Source rows: %d\n", irows); fprintf(stdout, "Local north: %s\n", north_str); fprintf(stdout, "Local south: %s\n", south_str); fprintf(stdout, "Local west: %s\n", west_str); fprintf(stdout, "Local east: %s\n", east_str); } /* somehow approximate local ewres, nsres ?? (use 'g.region -m' on lat/lon side) */ exit(EXIT_SUCCESS); } /* Cut non-overlapping parts of input map */ if (!nocrop->answer) bordwalk(&outcellhd, &incellhd, &oproj, &iproj); /* Add 2 cells on each side for bilinear/cubic & future interpolation methods */ /* (should probably be a factor based on input and output resolution) */ incellhd.north += 2 * incellhd.ns_res; incellhd.east += 2 * incellhd.ew_res; incellhd.south -= 2 * incellhd.ns_res; incellhd.west -= 2 * incellhd.ew_res; if (incellhd.north > inorth) incellhd.north = inorth; if (incellhd.east > ieast) incellhd.east = ieast; if (incellhd.south < isouth) incellhd.south = isouth; if (incellhd.west < iwest) incellhd.west = iwest; Rast_set_input_window(&incellhd); /* And switch back to original location */ G__switch_env(); /* Adjust borders of output map */ if (!nocrop->answer) bordwalk(&incellhd, &outcellhd, &iproj, &oproj); #if 0 outcellhd.west = outcellhd.south = HUGE_VAL; outcellhd.east = outcellhd.north = -HUGE_VAL; for (row = 0; row < incellhd.rows; row++) { ycoord1 = Rast_row_to_northing((double)(row + 0.5), &incellhd); for (col = 0; col < incellhd.cols; col++) { xcoord1 = Rast_col_to_easting((double)(col + 0.5), &incellhd); pj_do_proj(&xcoord1, &ycoord1, &iproj, &oproj); if (xcoord1 > outcellhd.east) outcellhd.east = xcoord1; if (ycoord1 > outcellhd.north) outcellhd.north = ycoord1; if (xcoord1 < outcellhd.west) outcellhd.west = xcoord1; if (ycoord1 < outcellhd.south) outcellhd.south = ycoord1; } } #endif if (res->answer != NULL) /* set user defined resolution */ outcellhd.ns_res = outcellhd.ew_res = atof(res->answer); G_adjust_Cell_head(&outcellhd, 0, 0); Rast_set_output_window(&outcellhd); G_message(" "); G_message(_("Input:")); G_message(_("Cols: %d (%d)"), incellhd.cols, icols); G_message(_("Rows: %d (%d)"), incellhd.rows, irows); G_message(_("North: %f (%f)"), incellhd.north, inorth); G_message(_("South: %f (%f)"), incellhd.south, isouth); G_message(_("West: %f (%f)"), incellhd.west, iwest); G_message(_("East: %f (%f)"), incellhd.east, ieast); G_message(_("EW-res: %f"), incellhd.ew_res); G_message(_("NS-res: %f"), incellhd.ns_res); G_message(" "); G_message(_("Output:")); G_message(_("Cols: %d (%d)"), outcellhd.cols, ocols); G_message(_("Rows: %d (%d)"), outcellhd.rows, orows); G_message(_("North: %f (%f)"), outcellhd.north, onorth); G_message(_("South: %f (%f)"), outcellhd.south, osouth); G_message(_("West: %f (%f)"), outcellhd.west, owest); G_message(_("East: %f (%f)"), outcellhd.east, oeast); G_message(_("EW-res: %f"), outcellhd.ew_res); G_message(_("NS-res: %f"), outcellhd.ns_res); G_message(" "); /* open and read the relevant parts of the input map and close it */ G__switch_env(); Rast_set_input_window(&incellhd); fdi = Rast_open_old(inmap->answer, setname); cell_type = Rast_get_map_type(fdi); ibuffer = readcell(fdi, memory->answer); Rast_close(fdi); G__switch_env(); Rast_set_output_window(&outcellhd); if (strcmp(interpol->answer, "nearest") == 0) { fdo = Rast_open_new(mapname, cell_type); obuffer = (CELL *) Rast_allocate_output_buf(cell_type); } else { fdo = Rast_open_fp_new(mapname); cell_type = FCELL_TYPE; obuffer = (FCELL *) Rast_allocate_output_buf(cell_type); } cell_size = Rast_cell_size(cell_type); xcoord1 = xcoord2 = outcellhd.west + (outcellhd.ew_res / 2); /**/ ycoord1 = ycoord2 = outcellhd.north - (outcellhd.ns_res / 2); /**/ G_important_message(_("Projecting...")); G_percent(0, outcellhd.rows, 2); for (row = 0; row < outcellhd.rows; row++) { obufptr = obuffer; for (col = 0; col < outcellhd.cols; col++) { /* project coordinates in output matrix to */ /* coordinates in input matrix */ if (pj_do_proj(&xcoord1, &ycoord1, &oproj, &iproj) < 0) Rast_set_null_value(obufptr, 1, cell_type); else { /* convert to row/column indices of input matrix */ col_idx = (xcoord1 - incellhd.west) / incellhd.ew_res; row_idx = (incellhd.north - ycoord1) / incellhd.ns_res; /* and resample data point */ interpolate(ibuffer, obufptr, cell_type, &col_idx, &row_idx, &incellhd); } obufptr = G_incr_void_ptr(obufptr, cell_size); xcoord2 += outcellhd.ew_res; xcoord1 = xcoord2; ycoord1 = ycoord2; } Rast_put_row(fdo, obuffer, cell_type); xcoord1 = xcoord2 = outcellhd.west + (outcellhd.ew_res / 2); ycoord2 -= outcellhd.ns_res; ycoord1 = ycoord2; G_percent(row, outcellhd.rows - 1, 2); } Rast_close(fdo); if (have_colors > 0) { Rast_write_colors(mapname, G_mapset(), &colr); Rast_free_colors(&colr); } Rast_short_history(mapname, "raster", &history); Rast_command_history(&history); Rast_write_history(mapname, &history); G_done_msg(NULL); exit(EXIT_SUCCESS); }
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); }
OGRSpatialReferenceH GPJ_grass_to_osr(struct Key_Value * proj_info, struct Key_Value * proj_units) { struct pj_info pjinfo; char *proj4, *proj4mod, *wkt, *modwkt, *startmod, *lastpart; OGRSpatialReferenceH hSRS, hSRS2; OGRErr errcode; struct gpj_datum dstruct; struct gpj_ellps estruct; size_t len; const char *ellpskv, *unit, *unfact; char *ellps, *ellpslong, *datum, *params, *towgs84, *datumlongname, *start, *end; const char *sysname, *osrunit, *osrunfact; double a, es, rf; int haveparams = 0; if ((proj_info == NULL) || (proj_units == NULL)) return NULL; hSRS = OSRNewSpatialReference(NULL); if (pj_get_kv(&pjinfo, proj_info, proj_units) < 0) { G_warning(_("Unable parse GRASS PROJ_INFO file")); return NULL; } if ((proj4 = pj_get_def(pjinfo.pj, 0)) == NULL) { G_warning(_("Unable get PROJ.4-style parameter string")); return NULL; } pj_free(pjinfo.pj); unit = G_find_key_value("unit", proj_units); unfact = G_find_key_value("meters", proj_units); if (unfact != NULL && (strcmp(pjinfo.proj, "ll") != 0)) G_asprintf(&proj4mod, "%s +to_meter=%s", proj4, unfact); else proj4mod = G_store(proj4); pj_dalloc(proj4); if ((errcode = OSRImportFromProj4(hSRS, proj4mod)) != OGRERR_NONE) { G_warning(_("OGR can't parse PROJ.4-style parameter string: " "%s (OGR Error code was %d)"), proj4mod, errcode); return NULL; } G_free(proj4mod); if ((errcode = OSRExportToWkt(hSRS, &wkt)) != OGRERR_NONE) { G_warning(_("OGR can't get WKT-style parameter string " "(OGR Error code was %d)"), errcode); return NULL; } ellpskv = G_find_key_value("ellps", proj_info); GPJ__get_ellipsoid_params(proj_info, &a, &es, &rf); haveparams = GPJ__get_datum_params(proj_info, &datum, ¶ms); if(ellpskv != NULL) ellps = G_store(ellpskv); else ellps = NULL; if ((datum == NULL) || (GPJ_get_datum_by_name(datum, &dstruct) < 0)) { datumlongname = G_store("unknown"); if (ellps == NULL) ellps = G_store("unnamed"); } else { datumlongname = G_store(dstruct.longname); if (ellps == NULL) ellps = G_store(dstruct.ellps); GPJ_free_datum(&dstruct); } G_free(datum); if (GPJ_get_ellipsoid_by_name(ellps, &estruct) > 0) { ellpslong = G_store(estruct.longname); DatumNameMassage(&ellpslong); GPJ_free_ellps(&estruct); } else ellpslong = G_store(ellps); startmod = strstr(wkt, "GEOGCS"); lastpart = strstr(wkt, "PRIMEM"); len = strlen(wkt) - strlen(startmod); wkt[len] = '\0'; if (haveparams == 2) { /* Only put datum params into the WKT if they were specifically * specified in PROJ_INFO */ char *paramkey, *paramvalue; paramkey = strtok(params, "="); paramvalue = params + strlen(paramkey) + 1; if (G_strcasecmp(paramkey, "towgs84") == 0) G_asprintf(&towgs84, ",TOWGS84[%s]", paramvalue); else towgs84 = G_store(""); G_free(params); } else towgs84 = G_store(""); sysname = OSRGetAttrValue(hSRS, "PROJCS", 0); if (sysname == NULL) { /* Not a projected co-ordinate system */ start = G_store(""); end = G_store(""); } else { if ((strcmp(sysname, "unnamed") == 0) && (G_find_key_value("name", proj_info) != NULL)) G_asprintf(&start, "PROJCS[\"%s\",", G_find_key_value("name", proj_info)); else start = G_store(wkt); osrunit = OSRGetAttrValue(hSRS, "UNIT", 0); osrunfact = OSRGetAttrValue(hSRS, "UNIT", 1); if ((unfact == NULL) || (G_strcasecmp(osrunit, "unknown") != 0)) end = G_store(""); else { char *buff; double unfactf = atof(unfact); G_asprintf(&buff, ",UNIT[\"%s\",", osrunit); startmod = strstr(lastpart, buff); len = strlen(lastpart) - strlen(startmod); lastpart[len] = '\0'; G_free(buff); if (unit == NULL) unit = "unknown"; G_asprintf(&end, ",UNIT[\"%s\",%.16g]]", unit, unfactf); } } OSRDestroySpatialReference(hSRS); G_asprintf(&modwkt, "%sGEOGCS[\"%s\",DATUM[\"%s\",SPHEROID[\"%s\",%.16g,%.16g]%s],%s%s", start, ellps, datumlongname, ellpslong, a, rf, towgs84, lastpart, end); hSRS2 = OSRNewSpatialReference(modwkt); G_free(modwkt); CPLFree(wkt); G_free(start); G_free(ellps); G_free(datumlongname); G_free(ellpslong); G_free(towgs84); G_free(end); return hSRS2; }