/* **************************************************************************** * * MODULE: gis library * AUTHOR(S): Andreas Lange - andreas.lange@rhein-main.de * Paul Kelly - paul-grass@stjohnspoint.co.uk * PURPOSE: provide functions for reading datum parameters from the * location database. * COPYRIGHT: (C) 2000, 2003 by the GRASS Development Team * * This program is free software under the GNU General Public * License (>=v2). Read the file COPYING that comes with GRASS * for details. * *****************************************************************************/ #define DATUMTABLE "/etc/proj/datum.table" #include #include #include #include #include #include static struct table { struct datum { char *name; /* Short Name / acronym of map datum */ char *descr; /* Long Name for map datum */ char *ellps; /* acronym for ellipsoid used with this datum */ double dx; /* delta x */ double dy; /* delta y */ double dz; /* delta z */ } *datums; int size; int count; int initialized; } table; static int compare_table_names(const void *, const void *); int G_get_datum_by_name(const char *name) { int i; G_read_datum_table(); for (i = 0; i < table.count; i++) if (G_strcasecmp(name, table.datums[i].name) == 0) return i; return -1; } const char *G_datum_name(int n) { G_read_datum_table(); if (n < 0 || n >= table.count) return NULL; return table.datums[n].name; } const char *G_datum_description(int n) { G_read_datum_table(); if (n < 0 || n >= table.count) return NULL; return table.datums[n].descr; } const char *G_datum_ellipsoid(int n) { G_read_datum_table(); if (n < 0 || n >= table.count) return NULL; return table.datums[n].ellps; } /*********************************************************** * G_get_datumparams_from_projinfo(projinfo, datumname, params) * struct Key_Value *projinfo Set of key_value pairs containing * projection information in PROJ_INFO file * format * char *datumname Pointer into which a string containing * the datum name (if present) will be * placed. * char *params Pointer into which a string containing * the datum parameters (if present) will * be placed. * * Extract the datum transformation-related parameters from a * set of general PROJ_INFO parameters. * This function can be used to test if a location set-up * supports datum transformation. * * returns: -1 error or no datum information found, * 1 only datum name found, 2 params found ************************************************************/ int G_get_datumparams_from_projinfo(const struct Key_Value *projinfo, char *datumname, char *params) { int returnval = -1; if (NULL != G_find_key_value("datum", projinfo)) { sprintf(datumname, G_find_key_value("datum", projinfo)); returnval = 1; } if (G_find_key_value("datumparams", projinfo) != NULL) { sprintf(params, G_find_key_value("datumparams", projinfo)); returnval = 2; } else if (G_find_key_value("nadgrids", projinfo) != NULL) { sprintf(params, "nadgrids=%s", G_find_key_value("nadgrids", projinfo)); returnval = 2; } else if (G_find_key_value("towgs84", projinfo) != NULL) { sprintf(params, "towgs84=%s", G_find_key_value("towgs84", projinfo)); returnval = 2; } else if (G_find_key_value("dx", projinfo) != NULL && G_find_key_value("dy", projinfo) != NULL && G_find_key_value("dz", projinfo) != NULL) { sprintf(params, "towgs84=%s,%s,%s", G_find_key_value("dx", projinfo), G_find_key_value("dy", projinfo), G_find_key_value("dz", projinfo)); returnval = 2; } return returnval; } void G_read_datum_table(void) { FILE *fd; char file[GPATH_MAX]; char buf[1024]; int line; if (G_is_initialized(&table.initialized)) return; sprintf(file, "%s%s", G_gisbase(), DATUMTABLE); fd = fopen(file, "r"); if (!fd) { G_warning(_("unable to open datum table file: %s"), file); G_initialize_done(&table.initialized); return; } for (line = 1; G_getl2(buf, sizeof(buf), fd); line++) { char name[100], descr[100], ellps[100]; struct datum *t; G_strip(buf); if (*buf == '\0' || *buf == '#') continue; if (table.count >= table.size) { table.size += 50; table.datums = G_realloc(table.datums, table.size * sizeof(struct datum)); } t = &table.datums[table.count]; if (sscanf(buf, "%s \"%99[^\"]\" %s dx=%lf dy=%lf dz=%lf", name, descr, ellps, &t->dx, &t->dy, &t->dz) != 6) { G_warning(_("error in datum table file, line %d"), line); continue; } t->name = G_store(name); t->descr = G_store(descr); t->ellps = G_store(ellps); table.count++; } qsort(table.datums, table.count, sizeof(struct datum), compare_table_names); G_initialize_done(&table.initialized); } static int compare_table_names(const void *aa, const void *bb) { const struct datum *a = aa; const struct datum *b = bb; return G_strcasecmp(a->name, b->name); }