GRASS Programmer's Manual  6.4.2(2012)
gis/datum.c
Go to the documentation of this file.
00001 /*
00002  ****************************************************************************
00003  *
00004  * MODULE:       gis library
00005  * AUTHOR(S):    Andreas Lange - andreas.lange@rhein-main.de
00006  *               Paul Kelly - paul-grass@stjohnspoint.co.uk
00007  * PURPOSE:      provide functions for reading datum parameters from the
00008  *               location database.     
00009  * COPYRIGHT:    (C) 2000, 2003 by the GRASS Development Team
00010  *
00011  *               This program is free software under the GNU General Public
00012  *               License (>=v2). Read the file COPYING that comes with GRASS
00013  *               for details.
00014  *
00015  *****************************************************************************/
00016 
00017 #define DATUMTABLE "/etc/datum.table"
00018 
00019 #include <unistd.h>
00020 #include <string.h>
00021 #include <ctype.h>
00022 #include <stdlib.h>
00023 
00024 #include <grass/gis.h>
00025 #include <grass/glocale.h>
00026 
00027 static struct table
00028 {
00029     char *name;                 /* Short Name / acronym of map datum */
00030     char *descr;                /* Long Name for map datum */
00031     char *ellps;                /* acronym for ellipsoid used with this datum */
00032     double dx;                  /* delta x */
00033     double dy;                  /* delta y */
00034     double dz;                  /* delta z */
00035 } *table;
00036 
00037 static int size;
00038 static int count = -1;
00039 
00040 static int compare_table_names(const void *, const void *);
00041 static void read_datum_table(void);
00042 
00043 int G_get_datum_by_name(const char *name)
00044 {
00045     int i;
00046 
00047     read_datum_table();
00048 
00049     for (i = 0; i < count; i++)
00050         if (G_strcasecmp(name, table[i].name) == 0)
00051             return i;
00052 
00053     return -1;
00054 }
00055 
00056 char *G_datum_name(int n)
00057 {
00058     read_datum_table();
00059 
00060     if (n < 0 || n >= count)
00061         return NULL;
00062 
00063     return table[n].name;
00064 }
00065 
00066 char *G_datum_description(int n)
00067 {
00068     read_datum_table();
00069 
00070     if (n < 0 || n >= count)
00071         return NULL;
00072 
00073     return table[n].descr;
00074 }
00075 
00076 char *G_datum_ellipsoid(int n)
00077 {
00078     read_datum_table();
00079 
00080     if (n < 0 || n >= count)
00081         return NULL;
00082 
00083     return table[n].ellps;
00084 }
00085 
00086 /***********************************************************
00087  *  G_get_datumparams_from_projinfo(projinfo, datumname, params)
00088  *     struct Key_Value *projinfo Set of key_value pairs containing
00089  *                       projection information in PROJ_INFO file
00090  *                       format
00091  *     char *datumname   Pointer into which a string containing
00092  *                       the datum name (if present) will be
00093  *                       placed.
00094  *     char *params      Pointer into which a string containing
00095  *                       the datum parameters (if present) will
00096  *                       be placed.
00097  *
00098  *  Extract the datum transformation-related parameters from a 
00099  *  set of general PROJ_INFO parameters.
00100  *  This function can be used to test if a location set-up 
00101  *  supports datum transformation.
00102  *  
00103  *  returns: -1 error or no datum information found, 
00104  *           1 only datum name found, 2 params found
00105  ************************************************************/
00106 
00107 int G_get_datumparams_from_projinfo(const struct Key_Value *projinfo,
00108                                     char *datumname, char *params)
00109 {
00110     int returnval = -1;
00111 
00112     if (NULL != G_find_key_value("datum", projinfo)) {
00113         sprintf(datumname, G_find_key_value("datum", projinfo));
00114         returnval = 1;
00115     }
00116 
00117     if (G_find_key_value("datumparams", projinfo) != NULL) {
00118         sprintf(params, G_find_key_value("datumparams", projinfo));
00119         returnval = 2;
00120     }
00121     else if (G_find_key_value("nadgrids", projinfo) != NULL) {
00122         sprintf(params, "nadgrids=%s",
00123                 G_find_key_value("nadgrids", projinfo));
00124         returnval = 2;
00125     }
00126     else if (G_find_key_value("towgs84", projinfo) != NULL) {
00127         sprintf(params, "towgs84=%s", G_find_key_value("towgs84", projinfo));
00128         returnval = 2;
00129     }
00130     else if (G_find_key_value("dx", projinfo) != NULL
00131              && G_find_key_value("dy", projinfo) != NULL
00132              && G_find_key_value("dz", projinfo) != NULL) {
00133         sprintf(params, "towgs84=%s,%s,%s",
00134                 G_find_key_value("dx", projinfo),
00135                 G_find_key_value("dy", projinfo),
00136                 G_find_key_value("dz", projinfo));
00137         returnval = 2;
00138     }
00139 
00140     return returnval;
00141 
00142 }
00143 
00144 static void read_datum_table(void)
00145 {
00146     FILE *fd;
00147     char file[1024];
00148     char buf[1024];
00149     int line;
00150 
00151     if (count >= 0)
00152         return;
00153 
00154     count = 0;
00155 
00156     sprintf(file, "%s%s", G_gisbase(), DATUMTABLE);
00157 
00158     fd = fopen(file, "r");
00159     if (!fd) {
00160         G_warning(_("unable to open datum table file: %s"), file);
00161         return;
00162     }
00163 
00164     for (line = 1; G_getl2(buf, sizeof(buf), fd); line++) {
00165         char name[100], descr[100], ellps[100];
00166         struct table *t;
00167 
00168         G_strip(buf);
00169         if (*buf == '\0' || *buf == '#')
00170             continue;
00171 
00172         if (count >= size) {
00173             size += 50;
00174             table = G_realloc(table, size * sizeof(struct table));
00175         }
00176 
00177         t = &table[count];
00178 
00179         if (sscanf(buf, "%s \"%99[^\"]\" %s dx=%lf dy=%lf dz=%lf",
00180                    name, descr, ellps, &t->dx, &t->dy, &t->dz) != 6) {
00181             G_warning(_("error in datum table file, line %d"), line);
00182             continue;
00183         }
00184 
00185         t->name = G_store(name);
00186         t->descr = G_store(descr);
00187         t->ellps = G_store(ellps);
00188 
00189         count++;
00190     }
00191 
00192     qsort(table, count, sizeof(struct table), compare_table_names);
00193 }
00194 
00195 static int compare_table_names(const void *aa, const void *bb)
00196 {
00197     const struct table *a = aa;
00198     const struct table *b = bb;
00199 
00200     return G_strcasecmp(a->name, b->name);
00201 }
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines