/* returns 0 on success, 1 on failure */ int G__write_fp_format(int fd) { struct fileinfo *fcb = &G__.fileinfo[fd]; struct Key_Value *format_kv; char path[GPATH_MAX]; int stat; if (fcb->map_type == CELL_TYPE) { G_warning(_("unable to write f_format file for CELL maps")); return 0; } format_kv = G_create_key_value(); if (fcb->map_type == FCELL_TYPE) G_set_key_value("type", "float", format_kv); else G_set_key_value("type", "double", format_kv); G_set_key_value("byte_order", "xdr", format_kv); if (fcb->open_mode == OPEN_NEW_COMPRESSED) G_set_key_value("lzw_compression_bits", "-1", format_kv); G__make_mapset_element_misc("cell_misc", fcb->name); G__file_name_misc(path, "cell_misc", FORMAT_FILE, fcb->name, fcb->mapset); G_write_key_value_file(path, format_kv, &stat); G_free_key_value(format_kv); return stat; }
/** * This routine returns the ellipsoid parameters from the database. * If the PROJECTION_FILE exists in the PERMANENT mapset, read info from * that file, otherwise return WGS 84 values. * * \return 1 ok, 0 default values used. * Dies with diagnostic if there is an error **/ int GPJ_get_ellipsoid_params(double *a, double *e2, double *rf) { int ret; struct Key_Value *proj_keys = G_get_projinfo(); if (proj_keys == NULL) proj_keys = G_create_key_value(); ret = GPJ__get_ellipsoid_params(proj_keys, a, e2, rf); G_free_key_value(proj_keys); return ret; }
int set_datum(char *datum) { struct gpj_datum dstruct; struct Key_Value *temp_projinfo; int i; if (cellhd.proj == PROJECTION_XY) return 0; if (!datum || GPJ_get_datum_by_name(datum, &dstruct) < 0) { G_fatal_error(_("Invalid datum code <%s>"), datum); return 0; } temp_projinfo = G_create_key_value(); /* Copy old PROJ_INFO, skipping out any keys related * to datum or ellipsoid parameters */ for (i = 0; i < projinfo->nitems; i++) { if (strcmp(projinfo->key[i], "datum") == 0 || strcmp(projinfo->key[i], "dx") == 0 || strcmp(projinfo->key[i], "dy") == 0 || strcmp(projinfo->key[i], "dz") == 0 || strcmp(projinfo->key[i], "datumparams") == 0 || strcmp(projinfo->key[i], "nadgrids") == 0 || strcmp(projinfo->key[i], "towgs84") == 0 || strcmp(projinfo->key[i], "ellps") == 0 || strcmp(projinfo->key[i], "a") == 0 || strcmp(projinfo->key[i], "b") == 0 || strcmp(projinfo->key[i], "es") == 0 || strcmp(projinfo->key[i], "f") == 0 || strcmp(projinfo->key[i], "rf") == 0) continue; G_set_key_value(projinfo->key[i], projinfo->value[i], temp_projinfo); } /* Finally add datum and ellipsoid names */ G_set_key_value("datum", dstruct.name, temp_projinfo); G_message(_("Datum set to <%s>"), dstruct.name); G_set_key_value("ellps", dstruct.ellps, temp_projinfo); G_message(_("Ellipsoid set to <%s>"), dstruct.ellps); /* Destroy original key/value structure and replace with new one */ G_free_key_value(projinfo); projinfo = temp_projinfo; return 1; }
int main(int argc, char *argv[]) { struct GModule *module; int Out_proj; int out_stat; int old_zone, old_proj; int i; int stat; char cmnd2[500]; char proj_out[20], proj_name[50], set_name[20]; char path[1024], buffa[1024], buffb[1024], answer[200], answer1[200]; char answer2[200], buff[1024]; char tmp_buff[20], *buf; struct Key_Value *old_proj_keys, *out_proj_keys, *in_unit_keys; double aa, e2; double f; FILE *FPROJ; int exist = 0; char spheroid[100]; int j, k, sph_check; struct Cell_head cellhd; char datum[100], dat_ellps[100], dat_params[100]; struct proj_parm *proj_parms; G_gisinit(argv[0]); module = G_define_module(); G_add_keyword(_("general")); G_add_keyword(_("projection")); module->description = _("Interactively reset the location's projection settings."); if (G_parser(argc, argv)) exit(EXIT_FAILURE); if (strcmp(G_mapset(), "PERMANENT") != 0) G_fatal_error(_("You must be in the PERMANENT mapset to run g.setproj")); /*** * no longer necessary, table is a static struct * init_unit_table(); ***/ sprintf(set_name, "PERMANENT"); G_file_name(path, "", PROJECTION_FILE, set_name); /* get the output projection parameters, if existing */ /* Check for ownership here */ stat = G__mapset_permissions(set_name); if (stat == 0) { G_fatal_error(_("PERMANENT: permission denied")); } G_get_default_window(&cellhd); if (-1 == G_set_window(&cellhd)) G_fatal_error(_("Current region cannot be set")); if (G_get_set_window(&cellhd) == -1) G_fatal_error(_("Retrieving and setting region failed")); Out_proj = cellhd.proj; old_zone = cellhd.zone; old_proj = cellhd.proj; if (access(path, 0) == 0) { exist = 1; FPROJ = fopen(path, "r"); old_proj_keys = G_fread_key_value(FPROJ); fclose(FPROJ); buf = G_find_key_value("name", old_proj_keys); fprintf(stderr, "\nWARNING: A projection file already exists for this location\n(Filename '%s')\n", path); fprintf(stderr, "\nThis file contains all the parameters for the location's projection:\n %s\n", buf); fprintf(stderr, "\n Overriding this information implies that the old projection parameters\n" " were incorrect. If you change the parameters, all existing data will\n" " be interpreted differently by the projection software.\n%c%c%c", 7, 7, 7); fprintf(stderr, " GRASS will not re-project your data automatically.\n\n"); if (!G_yes (_("Would you still like to change some of the parameters?"), 0)) { G_message(_("The projection information will not be updated")); leave(SP_NOCHANGE); } } out_proj_keys = G_create_key_value(); if (exist) { buf = G_find_key_value("zone", old_proj_keys); if (buf != NULL) sscanf(buf, "%d", &zone); if (zone != old_zone) { G_warning(_("Zone in default geographic region definition: %d\n" " is different from zone in PROJ_INFO file: %d"), old_zone, zone); old_zone = zone; } } switch (Out_proj) { case 0: /* No projection/units */ if (!exist) { /* leap frog over code, and just make sure we remove the file */ G_warning(_("XY-location cannot be projected")); goto write_file; break; } case PROJECTION_UTM: if (!exist) { sprintf(proj_name, "%s", G__projection_name(PROJECTION_UTM)); sprintf(proj_out, "utm"); break; } case PROJECTION_SP: if (!exist) { sprintf(proj_name, "%s", G__projection_name(PROJECTION_SP)); sprintf(proj_out, "stp"); break; } case PROJECTION_LL: if (!exist) { sprintf(proj_name, "%s", G__projection_name(PROJECTION_LL)); sprintf(proj_out, "ll"); break; } case PROJECTION_OTHER: if (G_ask_proj_name(proj_out, proj_name) < 0) leave(SP_NOCHANGE); if (G_strcasecmp(proj_out, "LL") == 0) Out_proj = PROJECTION_LL; else if (G_strcasecmp(proj_out, "UTM") == 0) Out_proj = PROJECTION_UTM; else if (G_strcasecmp(proj_out, "STP") == 0) Out_proj = PROJECTION_SP; break; default: G_fatal_error(_("Unknown projection")); } cellhd.proj = Out_proj; proj_parms = get_proj_parms(proj_out); if (!proj_parms) G_fatal_error(_("Projection %s is not specified in the file 'proj-parms.table'"), proj_out); G_set_key_value("name", proj_name, out_proj_keys); sph_check = 0; if (G_yes (_("Do you wish to specify a geodetic datum for this location?"), 1)) { char lbuf[100], lbufa[100]; if (exist && (G_get_datumparams_from_projinfo(old_proj_keys, lbuf, lbufa) == 2)) { G_strip(lbuf); if ((i = G_get_datum_by_name(lbuf)) > 0) { G_message(_("The current datum is %s (%s)"), G_datum_name(i), G_datum_description(i)); if (G_yes (_("Do you wish to change the datum (or datum transformation parameters)?"), 0)) sph_check = ask_datum(datum, dat_ellps, dat_params); else { sprintf(datum, lbuf); sprintf(dat_params, lbufa); sprintf(dat_ellps, G_datum_ellipsoid(i)); sph_check = 1; G_message(_("The datum information has not been changed")); } } else sph_check = ask_datum(datum, dat_ellps, dat_params); } else sph_check = ask_datum(datum, dat_ellps, dat_params); } if (sph_check > 0) { char *paramkey, *paramvalue; /* write out key/value pairs to out_proj_keys */ if (G_strcasecmp(datum, "custom") != 0) G_set_key_value("datum", datum, out_proj_keys); /* G_set_key_value("datumparams", dat_params, out_proj_keys); */ paramkey = strtok(dat_params, "="); paramvalue = dat_params + strlen(paramkey) + 1; G_set_key_value(paramkey, paramvalue, out_proj_keys); sprintf(spheroid, "%s", dat_ellps); } else { /***************** GET spheroid **************************/ if (Out_proj != PROJECTION_SP) { /* some projections have * fixed spheroids */ if (G_strcasecmp(proj_out, "ALSK") == 0 || G_strcasecmp(proj_out, "GS48") == 0 || G_strcasecmp(proj_out, "GS50") == 0) { sprintf(spheroid, "%s", "clark66"); G_set_key_value("ellps", spheroid, out_proj_keys); sph_check = 1; } else if (G_strcasecmp(proj_out, "LABRD") == 0 || G_strcasecmp(proj_out, "NZMG") == 0) { sprintf(spheroid, "%s", "international"); G_set_key_value("ellps", spheroid, out_proj_keys); sph_check = 1; } else if (G_strcasecmp(proj_out, "SOMERC") == 0) { sprintf(spheroid, "%s", "bessel"); G_set_key_value("ellps", spheroid, out_proj_keys); sph_check = 1; } else if (G_strcasecmp(proj_out, "OB_TRAN") == 0) { /* Hard coded to use "Equidistant Cylincrical" * until g.setproj has been changed to run * recurively, to allow input of options for * a second projection, MHu991010 */ G_set_key_value("o_proj", "eqc", out_proj_keys); sph_check = 2; } else { if (exist && (buf = G_find_key_value("ellps", old_proj_keys)) != NULL) { strcpy(spheroid, buf); G_strip(spheroid); if (G_get_spheroid_by_name(spheroid, &aa, &e2, &f)) { /* if legal ellips. exist, ask wether or not to change it */ G_message(_("The current ellipsoid is %s"), spheroid); if (G_yes (_("Do you want to change ellipsoid parameter?"), 0)) sph_check = G_ask_ellipse_name(spheroid); else { G_message(_("The ellipse information has not been changed")); sph_check = 1; } } /* the val is legal */ else sph_check = G_ask_ellipse_name(spheroid); } else sph_check = G_ask_ellipse_name(spheroid); } } if (sph_check > 0) { if (sph_check == 2) { /* ask radius */ if (exist) { buf = G_find_key_value("a", old_proj_keys); if ((buf != NULL) && (sscanf(buf, "%lf", &radius) == 1)) { G_message(_("The radius is currently %f"), radius); if (G_yes(_("Do you want to change the radius?"), 0)) radius = prompt_num_double(_("Enter radius for the sphere in meters"), RADIUS_DEF, 1); } } else radius = prompt_num_double(_("Enter radius for the sphere in meters"), RADIUS_DEF, 1); } /* end ask radius */ } } /*** END get spheroid ***/ /* create the PROJ_INFO & PROJ_UNITS files, if required */ if (G_strcasecmp(proj_out, "LL") == 0) ; else if (G_strcasecmp(proj_out, "STP") == 0) get_stp_proj(buffb); else if (sph_check != 2) { G_strip(spheroid); if (G_get_spheroid_by_name(spheroid, &aa, &e2, &f) == 0) G_fatal_error(_("Invalid input ellipsoid")); } write_file: /* ** NOTE the program will (hopefully) never exit abnormally ** after this point. Thus we know the file will be completely ** written out once it is opened for write */ if (exist) { sprintf(buff, "%s~", path); G_rename_file(path, buff); } if (Out_proj == 0) goto write_units; /* ** Include MISC parameters for PROJ_INFO */ if (G_strcasecmp(proj_out, "STP") == 0) { for (i = 0; i < strlen(buffb); i++) if (buffb[i] == ' ') buffb[i] = '\t'; sprintf(cmnd2, "%s\t\n", buffb); for (i = 0; i < strlen(cmnd2); i++) { j = k = 0; if (cmnd2[i] == '+') { while (cmnd2[++i] != '=') buffa[j++] = cmnd2[i]; buffa[j] = 0; while (cmnd2[++i] != '\t' && cmnd2[i] != '\n' && cmnd2[i] != 0) buffb[k++] = cmnd2[i]; buffb[k] = 0; G_set_key_value(buffa, buffb, out_proj_keys); } } } else if (G_strcasecmp(proj_out, "LL") == 0) { G_set_key_value("proj", "ll", out_proj_keys); G_set_key_value("ellps", spheroid, out_proj_keys); } else { if (sph_check != 2) { G_set_key_value("proj", proj_out, out_proj_keys); G_set_key_value("ellps", spheroid, out_proj_keys); sprintf(tmp_buff, "%.10f", aa); G_set_key_value("a", tmp_buff, out_proj_keys); sprintf(tmp_buff, "%.10f", e2); G_set_key_value("es", tmp_buff, out_proj_keys); sprintf(tmp_buff, "%.10f", f); G_set_key_value("f", tmp_buff, out_proj_keys); } else { G_set_key_value("proj", proj_out, out_proj_keys); /* G_set_key_value ("ellps", "sphere", out_proj_keys); */ sprintf(tmp_buff, "%.10f", radius); G_set_key_value("a", tmp_buff, out_proj_keys); G_set_key_value("es", "0.0", out_proj_keys); G_set_key_value("f", "0.0", out_proj_keys); } for (i = 0;; i++) { struct proj_parm *parm = &proj_parms[i]; struct proj_desc *desc; if (!parm->name) break; desc = get_proj_desc(parm->name); if (!desc) break; if (parm->ask) { if (G_strcasecmp(desc->type, "bool") == 0) { if (G_yes((char *)desc->desc, 0)) { G_set_key_value(desc->key, "defined", out_proj_keys); if (G_strcasecmp(parm->name, "SOUTH") == 0) cellhd.zone = -abs(cellhd.zone); } } else if (G_strcasecmp(desc->type, "lat") == 0) { double val; while (!get_LL_stuff(parm, desc, 1, &val)) ; sprintf(tmp_buff, "%.10f", val); G_set_key_value(desc->key, tmp_buff, out_proj_keys); } else if (G_strcasecmp(desc->type, "lon") == 0) { double val; while (!get_LL_stuff(parm, desc, 0, &val)) ; sprintf(tmp_buff, "%.10f", val); G_set_key_value(desc->key, tmp_buff, out_proj_keys); } else if (G_strcasecmp(desc->type, "float") == 0) { double val; while (!get_double(parm, desc, &val)) ; sprintf(tmp_buff, "%.10f", val); G_set_key_value(desc->key, tmp_buff, out_proj_keys); } else if (G_strcasecmp(desc->type, "int") == 0) { int val; while (!get_int(parm, desc, &val)) ; sprintf(tmp_buff, "%d", val); G_set_key_value(desc->key, tmp_buff, out_proj_keys); } else if (G_strcasecmp(desc->type, "zone") == 0) { if ((Out_proj == PROJECTION_UTM) && (old_zone != 0)) { G_message(_("The UTM zone is now set to %d"), old_zone); if (!G_yes (_("Do you want to change the UTM zone?"), 0)) { G_message(_("UTM zone information has not been updated")); zone = old_zone; break; } else { G_message(_("But if you change zone, all the existing " "data will be interpreted by projection software. " "GRASS will not automatically re-project or even " "change the headers for existing maps.")); if (!G_yes (_("Would you still like to change the UTM zone?"), 0)) { zone = old_zone; break; } } } /* UTM */ while (!get_zone()) ; sprintf(tmp_buff, "%d", zone); G_set_key_value("zone", tmp_buff, out_proj_keys); cellhd.zone = zone; } } else if (parm->def_exists) { /* don't ask, use the default */ if (G_strcasecmp(desc->type, "float") == 0 || G_strcasecmp(desc->type, "lat") == 0 || G_strcasecmp(desc->type, "lon") == 0) { sprintf(tmp_buff, "%.10f", parm->deflt); G_set_key_value(desc->key, tmp_buff, out_proj_keys); } else if (G_strcasecmp(desc->type, "int") == 0) { sprintf(tmp_buff, "%d", (int)parm->deflt); G_set_key_value(desc->key, tmp_buff, out_proj_keys); } } } /* for OPTIONS */ } /* create the PROJ_INFO & PROJ_UNITS files, if required */ G_write_key_value_file(path, out_proj_keys, &out_stat); if (out_stat != 0) { G_fatal_error(_("Error writing PROJ_INFO file <%s>"), path); } G_free_key_value(out_proj_keys); if (exist) G_free_key_value(old_proj_keys); write_units: G_file_name(path, "", UNIT_FILE, set_name); /* if we got this far, the user ** already affirmed to write over old info ** so if units file is here, remove it. */ if (access(path, 0) == 0) { sprintf(buff, "%s~", path); G_rename_file(path, buff); } if (Out_proj == 0) leave(0); { in_unit_keys = G_create_key_value(); switch (Out_proj) { case PROJECTION_UTM: G_set_key_value("unit", "meter", in_unit_keys); G_set_key_value("units", "meters", in_unit_keys); G_set_key_value("meters", "1.0", in_unit_keys); break; case PROJECTION_SP: for (;;) { do { fprintf(stderr, "\nSpecify the correct units to use:\n"); fprintf(stderr, "Enter the corresponding number\n"); fprintf(stderr, "1.\tUS Survey Foot (Default for State Plane 1927)\n"); fprintf(stderr, "2.\tInternational Foot\n"); fprintf(stderr, "3.\tMeter\n"); fprintf(stderr, ">"); } while (!G_gets(answer)); G_strip(answer); if (strcmp(answer, "1") == 0) { G_set_key_value("unit", "USfoot", in_unit_keys); G_set_key_value("units", "USfeet", in_unit_keys); G_set_key_value("meters", "0.30480060960121920243", in_unit_keys); break; } else if (strcmp(answer, "2") == 0) { G_set_key_value("unit", "foot", in_unit_keys); G_set_key_value("units", "feet", in_unit_keys); G_set_key_value("meters", "0.3048", in_unit_keys); break; } else if (strcmp(answer, "3") == 0) { G_set_key_value("unit", "meter", in_unit_keys); G_set_key_value("units", "meters", in_unit_keys); G_set_key_value("meters", "1.0", in_unit_keys); break; } else fprintf(stderr, "\nInvalid Entry (number 1 - 3)\n"); } break; case PROJECTION_LL: G_set_key_value("unit", "degree", in_unit_keys); G_set_key_value("units", "degrees", in_unit_keys); G_set_key_value("meters", "1.0", in_unit_keys); break; default: if (G_strcasecmp(proj_out, "LL") != 0) { fprintf(stderr, _("Enter plural form of units [meters]: ")); G_gets(answer); if (strlen(answer) == 0) { G_set_key_value("unit", "meter", in_unit_keys); G_set_key_value("units", "meters", in_unit_keys); G_set_key_value("meters", "1.0", in_unit_keys); } else { const struct proj_unit *unit; G_strip(answer); unit = get_proj_unit(answer); if (unit) { #ifdef FOO if (G_strcasecmp(proj_out, "STP") == 0 && !strcmp(answer, "feet")) { fprintf(stderr, "%cPROJECTION 99 State Plane cannot be in FEET.\n", 7); remove(path); /* remove file */ leave(SP_FATAL); } #endif G_set_key_value("unit", unit->unit, in_unit_keys); G_set_key_value("units", unit->units, in_unit_keys); sprintf(buffb, "%.10f", unit->fact); G_set_key_value("meters", buffb, in_unit_keys); } else { double unit_fact; while (1) { fprintf(stderr, _("Enter singular for unit: ")); G_gets(answer1); G_strip(answer1); if (strlen(answer1) > 0) break; } while (1) { fprintf(stderr, _("Enter conversion factor from %s to meters: "), answer); G_gets(answer2); G_strip(answer2); if (! (strlen(answer2) == 0 || (1 != sscanf(answer2, "%lf", &unit_fact)))) break; } G_set_key_value("unit", answer1, in_unit_keys); G_set_key_value("units", answer, in_unit_keys); sprintf(buffb, "%.10f", unit_fact); G_set_key_value("meters", buffb, in_unit_keys); } } } else { G_set_key_value("unit", "degree", in_unit_keys); G_set_key_value("units", "degrees", in_unit_keys); G_set_key_value("meters", "1.0", in_unit_keys); } } /* switch */ G_write_key_value_file(path, in_unit_keys, &out_stat); if (out_stat != 0) G_fatal_error(_("Error writing into UNITS output file <%s>"), path); G_free_key_value(in_unit_keys); } /* if */ if (G__put_window(&cellhd, "", "DEFAULT_WIND") < 0) G_fatal_error(_("Unable to write to DEFAULT_WIND region file")); fprintf(stderr, _("\nProjection information has been recorded for this location\n\n")); if ((old_zone != zone) | (old_proj != cellhd.proj)) { G_message(_("The geographic region information in WIND is now obsolete")); G_message(_("Run g.region -d to update it")); } leave(0); }
int set_datumtrans(int datumtrans, int force) { char *params, *datum = NULL; int paramsets, status; if (cellhd.proj == PROJECTION_XY) return 0; status = GPJ__get_datum_params(projinfo, &datum, ¶ms); G_debug(3, "set_datumtrans(): GPJ__get_datum_params() status=%d", status); G_free(params); if (datum) { /* A datum name is specified; need to determine if * there are parameters to choose from for this datum */ struct gpj_datum dstruct; if (GPJ_get_datum_by_name(datum, &dstruct) > 0) { char *defparams; paramsets = GPJ_get_default_datum_params_by_name(dstruct.name, &defparams); G_free(defparams); GPJ_free_datum(&dstruct); G_debug(3, "set_datumtrans(): datum transform terms found " "with %d options", paramsets); if (status == 1 && paramsets > 1) /* Parameters are missing and there is a choice to be made */ force = 1; } else { /* Datum name not found in table; can't do anything. */ G_debug(3, "set_datumtrans(): Datum name not found in table."); force = 0; } } else { /* No datum name; can't do anything. */ G_debug(3, "set_datumtrans(): Datum name either invalid or not supplied."); force = 0; } if (force) { char *chosenparams = NULL; char *paramkey, *paramvalue; struct Key_Value *temp_projinfo; int i; /* First of all obtain the new parameters * through the supplied transform number index */ { struct gpj_datum_transform_list *list; if (datumtrans > paramsets) G_fatal_error ("Invalid transformation number %d; valid range is 1 to %d", datumtrans, paramsets); G_debug(3, "set_datumtrans(): looking up available datum " "transforms for <%s>", datum); list = GPJ_get_datum_transform_by_name(datum); if (list != NULL) { if (datumtrans == -1) { do { struct gpj_datum_transform_list *old = list; fprintf(stdout, "---\n%d\nUsed in %s\n%s\n%s\n", list->count, list->where_used, list->params, list->comment); list = list->next; GPJ_free_datum_transform(old); } while (list != NULL); exit(EXIT_SUCCESS); } else { do { struct gpj_datum_transform_list *old = list; if (list->count == datumtrans) chosenparams = G_store(list->params); list = list->next; GPJ_free_datum_transform(old); } while (list != NULL); } } } temp_projinfo = G_create_key_value(); /* Copy old PROJ_INFO, skipping out any keys related * to datum parameters */ for (i = 0; i < projinfo->nitems; i++) { if (strcmp(projinfo->key[i], "dx") == 0 || strcmp(projinfo->key[i], "dy") == 0 || strcmp(projinfo->key[i], "dz") == 0 || strcmp(projinfo->key[i], "datumparams") == 0 || strcmp(projinfo->key[i], "nadgrids") == 0 || strcmp(projinfo->key[i], "towgs84") == 0) continue; G_set_key_value(projinfo->key[i], projinfo->value[i], temp_projinfo); } /* Finally add new parameters (if we have them) */ if (chosenparams != NULL) { /* Now split 'chosenparams' into key/value format */ paramkey = strtok(chosenparams, "="); paramvalue = chosenparams + strlen(paramkey) + 1; G_set_key_value(paramkey, paramvalue, temp_projinfo); G_free(chosenparams); } /* Destroy original key/value structure and replace with new one */ G_free_key_value(projinfo); projinfo = temp_projinfo; } G_free(datum); return force; }
void make_link(const char *dsn_opt, const char *format, char *option_str, char **options) { int use_ogr; char *filename, *dsn; FILE *fp; struct Key_Value *key_val; key_val = G_create_key_value(); /* check for weird options */ if (G_strncasecmp(dsn_opt, "PG:", 3) == 0 && strcmp(format, "PostgreSQL") != 0) G_warning(_("Data source starts with \"PG:\" prefix, expecting \"PostgreSQL\" " "format (\"%s\" given)"), format); /* use OGR ? */ use_ogr = is_ogr(format); if (use_ogr) { filename = "OGR"; G_remove("", "PG"); } else { filename = "PG"; G_remove("", "OGR"); } /* be friendly, ignored 'PG:' prefix for GRASS-PostGIS data driver */ if (!use_ogr && strcmp(format, "PostgreSQL") == 0 && G_strncasecmp(dsn_opt, "PG:", 3) == 0) { int i, length; length = strlen(dsn_opt); dsn = (char *) G_malloc(length - 3); for (i = 3; i < length; i++) dsn[i-3] = dsn_opt[i]; dsn[length-3] = '\0'; } else { dsn = G_store(dsn_opt); } /* parse options for PG data format */ if (options && *options && !use_ogr) { int i; char *key, *value; i = 0; while (options[i]) { if (parse_option_pg(options[i++], &key, &value) != 0) continue; G_set_key_value(key, value, key_val); } } /* datasource section */ if (dsn) { if (use_ogr) G_set_key_value("dsn", dsn, key_val); else G_set_key_value("conninfo", dsn, key_val); } if (use_ogr) { /* OGR */ if (format) G_set_key_value("format", format, key_val); if (option_str) G_set_key_value("options", option_str, key_val); } else { /* PG */ G_set_key_value("format", "PostgreSQL", key_val); } /* save file - OGR or PG */ fp = G_fopen_new("", filename); if (!fp) G_fatal_error(_("Unable to create settings file")); if (G_fwrite_key_value(fp, key_val) < 0) G_fatal_error(_("Error writing settings file")); fclose(fp); if (use_ogr) G_verbose_message(_("Switched to OGR format (%s)"), G_find_key_value("format", key_val)); else G_verbose_message(_("Switched to PostGIS format")); G_free_key_value(key_val); }
int GPJ_osr_to_grass(struct Cell_head *cellhd, struct Key_Value **projinfo, struct Key_Value **projunits, OGRSpatialReferenceH hSRS, int datumtrans) { struct Key_Value *temp_projinfo; char *pszProj4 = NULL, *pszRemaining; char *pszProj = NULL; char *datum = NULL; struct gpj_datum dstruct; if (hSRS == NULL) goto default_to_xy; /* Set finder function for locating OGR csv co-ordinate system tables */ SetCSVFilenameHook(GPJ_set_csv_loc); /* Hopefully this doesn't do any harm if it wasn't in ESRI format * to start with... */ OSRMorphFromESRI(hSRS); /* -------------------------------------------------------------------- */ /* Set cellhd for well known coordinate systems. */ /* -------------------------------------------------------------------- */ if (!OSRIsGeographic(hSRS) && !OSRIsProjected(hSRS)) goto default_to_xy; if (cellhd) { int bNorth; if (OSRIsGeographic(hSRS)) { cellhd->proj = PROJECTION_LL; cellhd->zone = 0; } else if (OSRGetUTMZone(hSRS, &bNorth) != 0) { cellhd->proj = PROJECTION_UTM; cellhd->zone = OSRGetUTMZone(hSRS, &bNorth); if (!bNorth) cellhd->zone *= -1; } else { cellhd->proj = PROJECTION_OTHER; cellhd->zone = 0; } } /* -------------------------------------------------------------------- */ /* Get the coordinate system definition in PROJ.4 format. */ /* -------------------------------------------------------------------- */ if (OSRExportToProj4(hSRS, &pszProj4) != OGRERR_NONE) goto default_to_xy; /* -------------------------------------------------------------------- */ /* Parse the PROJ.4 string into key/value pairs. Do a bit of */ /* extra work to "GRASSify" the result. */ /* -------------------------------------------------------------------- */ temp_projinfo = G_create_key_value(); /* Create "local" copy of proj4 string so we can modify and free it * using GRASS functions */ pszRemaining = G_store(pszProj4); CPLFree(pszProj4); pszProj4 = pszRemaining; while ((pszRemaining = strstr(pszRemaining, "+")) != NULL) { char *pszToken, *pszValue; pszRemaining++; /* Advance pszRemaining to end of this token[=value] pair */ pszToken = pszRemaining; while (*pszRemaining != ' ' && *pszRemaining != '\0') pszRemaining++; if (*pszRemaining == ' ') { *pszRemaining = '\0'; pszRemaining++; } /* parse token, and value */ if (strstr(pszToken, "=") != NULL) { pszValue = strstr(pszToken, "="); *pszValue = '\0'; pszValue++; } else pszValue = "defined"; if (G_strcasecmp(pszToken, "proj") == 0) { /* The ll projection is known as longlat in PROJ.4 */ if (G_strcasecmp(pszValue, "longlat") == 0) pszValue = "ll"; pszProj = pszValue; continue; } /* Ellipsoid and datum handled separately below */ if (G_strcasecmp(pszToken, "ellps") == 0 || G_strcasecmp(pszToken, "a") == 0 || G_strcasecmp(pszToken, "b") == 0 || G_strcasecmp(pszToken, "es") == 0 || G_strcasecmp(pszToken, "rf") == 0 || G_strcasecmp(pszToken, "datum") == 0) continue; /* We will handle units separately */ if (G_strcasecmp(pszToken, "to_meter") == 0 || G_strcasecmp(pszToken, "units") == 0) continue; G_set_key_value(pszToken, pszValue, temp_projinfo); } *projinfo = G_create_key_value(); /* -------------------------------------------------------------------- */ /* Derive the user name for the projection. */ /* -------------------------------------------------------------------- */ if (pszProj) { char path[4095]; char name[80]; sprintf(path, "%s/etc/projections", G_gisbase()); if (G_lookup_key_value_from_file(path, pszProj, name, sizeof(name)) > 0) G_set_key_value("name", name, *projinfo); else G_set_key_value("name", pszProj, *projinfo); G_set_key_value("proj", pszProj, *projinfo); } else G_warning(_("No projection name! Projection parameters likely to be meaningless.")); /* -------------------------------------------------------------------- */ /* Find the GRASS datum name and choose parameters either */ /* interactively or not. */ /* -------------------------------------------------------------------- */ { const char *pszDatumNameConst = OSRGetAttrValue(hSRS, "DATUM", 0); struct datum_list *list, *listhead; char *dum1, *dum2, *pszDatumName; int paramspresent = GPJ__get_datum_params(temp_projinfo, &dum1, &dum2); if (pszDatumNameConst) { /* Need to make a new copy of the string so we don't mess * around with the memory inside the OGRSpatialReferenceH? */ pszDatumName = G_store(pszDatumNameConst); DatumNameMassage(&pszDatumName); list = listhead = read_datum_table(); while (list != NULL) { if (G_strcasecmp(pszDatumName, list->longname) == 0) { datum = G_store(list->name); break; } list = list->next; } free_datum_list(listhead); if (datum == NULL) { if (paramspresent < 2) /* Only give warning if no parameters present */ G_warning(_("Datum <%s> not recognised by GRASS and no parameters found"), pszDatumName); } else { G_set_key_value("datum", datum, *projinfo); if (paramspresent < 2) { /* If no datum parameters were imported from the OSR * object then we should use the set specified by datumtrans */ char *params, *chosenparams = NULL; int paramsets; paramsets = GPJ_get_default_datum_params_by_name(datum, ¶ms); if (paramsets < 0) G_warning(_("Datum <%s> apparently recognised by GRASS but no parameters found. " "You may want to look into this."), datum); else if (datumtrans > paramsets) { G_warning(_("Invalid transformation number %d; valid range is 1 to %d. " "Leaving datum transform parameters unspecified."), datumtrans, paramsets); datumtrans = 0; } if (paramsets > 0) { struct gpj_datum_transform_list *list, *old; list = GPJ_get_datum_transform_by_name(datum); if (list != NULL) { do { if (list->count == datumtrans) chosenparams = G_store(list->params); old = list; list = list->next; GPJ_free_datum_transform(old); } while (list != NULL); } } if (chosenparams != NULL) { char *paramkey, *paramvalue; paramkey = strtok(chosenparams, "="); paramvalue = chosenparams + strlen(paramkey) + 1; G_set_key_value(paramkey, paramvalue, *projinfo); G_free(chosenparams); } if (paramsets > 0) G_free(params); } } G_free(pszDatumName); } } /* -------------------------------------------------------------------- */ /* Determine an appropriate GRASS ellipsoid name if possible, or */ /* else just put a and es values into PROJ_INFO */ /* -------------------------------------------------------------------- */ if ((datum != NULL) && (GPJ_get_datum_by_name(datum, &dstruct) > 0)) { /* Use ellps name associated with datum */ G_set_key_value("ellps", dstruct.ellps, *projinfo); GPJ_free_datum(&dstruct); G_free(datum); } else { /* If we can't determine the ellipsoid from the datum, derive it * directly from "SPHEROID" parameters in WKT */ const char *pszSemiMajor = OSRGetAttrValue(hSRS, "SPHEROID", 1); const char *pszInvFlat = OSRGetAttrValue(hSRS, "SPHEROID", 2); if (pszSemiMajor != NULL && pszInvFlat != NULL) { char *ellps = NULL; struct ellps_list *list, *listhead; double a = atof(pszSemiMajor), invflat = atof(pszInvFlat), flat; double es; /* Allow for incorrect WKT describing a sphere where InvFlat * is given as 0 rather than inf */ if (invflat > 0) flat = 1 / invflat; else flat = 0; es = flat * (2.0 - flat); list = listhead = read_ellipsoid_table(0); while (list != NULL) { /* Try and match a and es against GRASS defined ellipsoids; * accept first one that matches. These numbers were found * by trial and error and could be fine-tuned, or possibly * a direct comparison of IEEE floating point values used. */ if ((a == list->a || fabs(a - list->a) < 0.1 || fabs(1 - a / list->a) < 0.0000001) && ((es == 0 && list->es == 0) || /* Special case for sphere */ (invflat == list->rf || fabs(invflat - list->rf) < 0.0000001))) { ellps = G_store(list->name); break; } list = list->next; } if (listhead != NULL) free_ellps_list(listhead); if (ellps == NULL) { /* If we weren't able to find a matching ellps name, set * a and es values directly from WKT-derived data */ char es_str[100]; G_set_key_value("a", (char *)pszSemiMajor, *projinfo); sprintf(es_str, "%.16g", es); G_set_key_value("es", es_str, *projinfo); } else { /* else specify the GRASS ellps name for readability */ G_set_key_value("ellps", ellps, *projinfo); G_free(ellps); } } } /* -------------------------------------------------------------------- */ /* Finally append the detailed projection parameters to the end */ /* -------------------------------------------------------------------- */ { int i; for (i = 0; i < temp_projinfo->nitems; i++) G_set_key_value(temp_projinfo->key[i], temp_projinfo->value[i], *projinfo); G_free_key_value(temp_projinfo); } G_free(pszProj4); /* -------------------------------------------------------------------- */ /* Set the linear units. */ /* -------------------------------------------------------------------- */ *projunits = G_create_key_value(); if (OSRIsGeographic(hSRS)) { /* We assume degrees ... someday we will be wrong! */ G_set_key_value("unit", "degree", *projunits); G_set_key_value("units", "degrees", *projunits); G_set_key_value("meters", "1.0", *projunits); } else { char szFormatBuf[256]; char *pszUnitsName = NULL; double dfToMeters; char *pszUnitsPlural, *pszStringEnd; dfToMeters = OSRGetLinearUnits(hSRS, &pszUnitsName); /* Workaround for the most obvious case when unit name is unknown */ if ((G_strcasecmp(pszUnitsName, "unknown") == 0) && (dfToMeters == 1.)) G_asprintf(&pszUnitsName, "meter"); G_set_key_value("unit", pszUnitsName, *projunits); /* Attempt at plural formation (WKT format doesn't store plural * form of unit name) */ pszUnitsPlural = G_malloc(strlen(pszUnitsName) + 3); strcpy(pszUnitsPlural, pszUnitsName); pszStringEnd = pszUnitsPlural + strlen(pszUnitsPlural) - 4; if (G_strcasecmp(pszStringEnd, "foot") == 0) { /* Special case for foot - change two o's to e's */ pszStringEnd[1] = 'e'; pszStringEnd[2] = 'e'; } else if (G_strcasecmp(pszStringEnd, "inch") == 0) { /* Special case for inch - add es */ pszStringEnd[4] = 'e'; pszStringEnd[5] = 's'; pszStringEnd[6] = '\0'; } else { /* For anything else add an s at the end */ pszStringEnd[4] = 's'; pszStringEnd[5] = '\0'; } G_set_key_value("units", pszUnitsPlural, *projunits); G_free(pszUnitsPlural); sprintf(szFormatBuf, "%.16g", dfToMeters); G_set_key_value("meters", szFormatBuf, *projunits); } return 2; /* -------------------------------------------------------------------- */ /* Fallback to returning an ungeoreferenced definition. */ /* -------------------------------------------------------------------- */ default_to_xy: if (cellhd != NULL) { cellhd->proj = PROJECTION_XY; cellhd->zone = 0; } *projinfo = NULL; *projunits = NULL; return 1; }
/*! \brief Create GDAL settings for given raster map \param name map name \param map_type map type (CELL, FCELL, DCELL) \return pointer to allocated GDAL_link structure \return NULL on error */ struct GDAL_link *Rast_create_gdal_link(const char *name, RASTER_MAP_TYPE map_type) { #ifdef GDAL_LINK char path[GPATH_MAX]; GDALDriverH driver; double transform[6]; struct GDAL_link *gdal; FILE *fp; struct Key_Value *key_val; char buf[32]; Rast__init_window(); Rast_init_gdal(); if (!G_is_initialized(&st->initialized)) { read_gdal_options(); st->projinfo = G_get_projinfo(); st->projunits = G_get_projunits(); #if 0 /* We cannot use GPJ_grass_to_wkt() here because that would create a circular dependency between libgis and libgproj */ if (st->projinfo && st->projunits) st->srswkt = GPJ_grass_to_wkt(st->projinfo, st->projunits); #endif G_initialize_done(&st->initialized); } gdal = G_calloc(1, sizeof(struct GDAL_link)); sprintf(path, "%s/%s%s", st->opts.dir, name, st->opts.ext); gdal->filename = G_store(path); gdal->band_num = 1; gdal->hflip = 0; gdal->vflip = 0; switch (map_type) { case CELL_TYPE: switch (R__.nbytes) { case 1: gdal->type = GDT_Byte; gdal->null_val = (DCELL) 0xFF; break; case 2: gdal->type = GDT_UInt16; gdal->null_val = (DCELL) 0xFFFF; break; case 3: case 4: gdal->type = GDT_Int32; gdal->null_val = (DCELL) 0x80000000U; break; } break; case FCELL_TYPE: gdal->type = GDT_Float32; Rast_set_d_null_value(&gdal->null_val, 1); break; case DCELL_TYPE: gdal->type = GDT_Float64; Rast_set_d_null_value(&gdal->null_val, 1); break; default: G_fatal_error(_("Invalid map type <%d>"), map_type); break; } driver = (*pGDALGetDriverByName) (st->opts.format); if (!driver) G_fatal_error(_("Unable to get <%s> driver"), st->opts.format); /* Does driver support GDALCreate ? */ if ((*pGDALGetMetadataItem) (driver, GDAL_DCAP_CREATE, NULL)) { gdal->data = (*pGDALCreate)(driver, gdal->filename, R__.wr_window.cols, R__.wr_window.rows, 1, gdal->type, st->opts.options); if (!gdal->data) G_fatal_error(_("Unable to create <%s> dataset using <%s> driver"), name, st->opts.format); } /* If not - create MEM driver for intermediate dataset. * Check if raster can be created at all (with GDALCreateCopy) */ else if ((*pGDALGetMetadataItem) (driver, GDAL_DCAP_CREATECOPY, NULL)) { GDALDriverH mem_driver; G_message(_("Driver <%s> does not support direct writing. " "Using MEM driver for intermediate dataset."), st->opts.format); mem_driver = (*pGDALGetDriverByName) ("MEM"); if (!mem_driver) G_fatal_error(_("Unable to get in-memory raster driver")); gdal->data = (*pGDALCreate)(mem_driver, "", R__.wr_window.cols, R__.wr_window.rows, 1, gdal->type, st->opts.options); if (!gdal->data) G_fatal_error(_("Unable to create <%s> dataset using memory driver"), name); } else G_fatal_error(_("Driver <%s> does not support creating rasters"), st->opts.format); gdal->band = (*pGDALGetRasterBand) (gdal->data, gdal->band_num); (*pGDALSetRasterNoDataValue) (gdal->band, gdal->null_val); /* Set Geo Transform */ transform[0] = R__.wr_window.west; transform[1] = R__.wr_window.ew_res; transform[2] = 0.0; transform[3] = R__.wr_window.north; transform[4] = 0.0; transform[5] = -R__.wr_window.ns_res; if ((*pGDALSetGeoTransform) (gdal->data, transform) >= CE_Failure) G_warning(_("Unable to set geo transform")); if (st->srswkt) if ((*pGDALSetProjection) (gdal->data, st->srswkt) == CE_Failure) G_warning(_("Unable to set projection")); fp = G_fopen_new_misc("cell_misc", "gdal", name); if (!fp) G_fatal_error(_("Unable to create cell_misc/%s/gdal file"), name); key_val = G_create_key_value(); G_set_key_value("file", gdal->filename, key_val); sprintf(buf, "%d", gdal->band_num); G_set_key_value("band", buf, key_val); sprintf(buf, "%.22g", gdal->null_val); G_set_key_value("null", buf, key_val); sprintf(buf, "%d", gdal->type); G_set_key_value("type", buf, key_val); if (G_fwrite_key_value(fp, key_val) < 0) G_fatal_error(_("Error writing cell_misc/%s/gdal file"), name); G_free_key_value(key_val); fclose(fp); return gdal; #else return NULL; #endif }