GRASS Programmer's Manual 6.4.1(2011)
|
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 }