123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251 |
- #include <string.h>
- #include <unistd.h>
- #include <grass/gis.h>
- #include <grass/glocale.h>
- #include <grass/config.h>
- #ifdef HAVE_PROJ_H
- #include <proj.h>
- #if PROJ_VERSION_MAJOR >= 6
- #define USE_PROJDB
- #endif
- #else
- #include <proj_api.h>
- #endif
- char *get_authority_names(void)
- {
- char *authnames;
- #ifdef USE_PROJDB
- /* PROJ 6 */
- int i, len;
- PROJ_STRING_LIST authlist = proj_get_authorities_from_database(NULL);
- len = 0;
- for (i = 0; authlist[i]; i++) {
- len += strlen(authlist[i]) + 1;
- }
- if (len > 0) {
- authnames = G_malloc((len + 1) * sizeof(char)); /* \0 */
- *authnames = '\0';
- for (i = 0; authlist[i]; i++) {
- if (i > 0)
- strcat(authnames, ",");
- strcat(authnames, authlist[i]);
- }
- }
- else {
- authnames = G_store("");
- }
- #else
- /* PROJ 4, 5 */
- /* there are various init files in share/proj/:
- * EPSG,GL27,IGNF,ITRF2000,ITRF2008,ITRF2014,nad27,nad83,esri
- * but they have different formats: bothering only with EPSG here */
- authnames = G_store("EPSG");
- #endif
- return authnames;
- }
- void list_codes(char *authname)
- {
- #ifdef USE_PROJDB
- /* PROJ 6+ */
- int i, crs_cnt;
- PROJ_CRS_INFO **proj_crs_info;
-
- crs_cnt = 0;
- proj_crs_info = proj_get_crs_info_list_from_database(NULL,
- authname, NULL, &crs_cnt);
- if (crs_cnt < 1)
- G_fatal_error(_("No codes found for authority %s"),
- authname);
-
- for (i = 0; i < crs_cnt; i++) {
- const char *proj_definition;
- char emptystr;
- PJ *pj;
- emptystr = '\0';
- pj = proj_create_from_database(NULL,
- proj_crs_info[i]->auth_name,
- proj_crs_info[i]->code,
- PJ_CATEGORY_CRS,
- 0, NULL);
- proj_definition = proj_as_proj_string(NULL, pj, PJ_PROJ_5, NULL);
- if (!proj_definition) {
- /* what to do with a CRS without proj string ? */
- G_debug(1, "No proj string for %s:%s",
- proj_crs_info[i]->auth_name,
- proj_crs_info[i]->code);
- proj_definition = &emptystr;
- }
- if (proj_definition) {
- fprintf(stdout, "%s|%s|%s\n", proj_crs_info[i]->code,
- proj_crs_info[i]->name,
- proj_definition);
- }
- proj_destroy(pj);
- }
- #else
- char pathname[GPATH_MAX];
- char code[GNAME_MAX], name[GNAME_MAX], proj_def[8192];
- FILE *fp;
- char buf[4096];
- int line;
- #ifdef HAVE_PROJ_H
- /* PROJ 5 */
- PJ_INIT_INFO init_info;
- if (G_strcasecmp(authname, "EPSG") == 0)
- authname = "epsg";
- init_info = proj_init_info(authname);
- sprintf(pathname, "%s", init_info.filename);
-
- if (access(pathname, F_OK) != 0)
- G_fatal_error(_("Unable to find init file %s"), authname);
- #else
- /* PROJ 4 */
- /* can't use pj_find_file() from the old proj api
- * because it does not exist in PROJ 4 */
- char *grass_proj_share;
- if (G_strcasecmp(authname, "EPSG") == 0)
- authname = "epsg";
- grass_proj_share = getenv("GRASS_PROJSHARE");
- if (!grass_proj_share)
- G_fatal_error(_("Environment variable GRASS_PROJSHARE is not set"));
- sprintf(pathname, "%s/%s", grass_proj_share, authname);
- G_convert_dirseps_to_host(pathname);
- #endif
- /* PROJ 4 / 5 */
-
- /* the init files do not have a common structure, thus restrict to epsg
- * see pj_init.c get_init_string() in PROJ 4 / 5 for a
- * generic init file parser, however without descriptive name */
- if (strcmp(authname, "epsg") != 0)
- G_fatal_error(_("Only epsg file is currently supported"));
-
- /* open the init file */
- fp = fopen(pathname, "r");
- if (!fp) {
- G_fatal_error(_("Unable to open init file <%s>"), authname);
- }
- code[0] = '\0';
- name[0] = '\0';
- proj_def[0] = '\0';
- /* print list of codes, names, definitions */
- for (line = 1; G_getl2(buf, sizeof(buf), fp); line++) {
- int buflen, bufstart;
- int i, j;
- G_strip(buf);
- buflen = strlen(buf);
-
- if (*buf == '\0' ||
- (buflen >= 10 && strncmp(buf, "<metadata>", 10) == 0)) {
- name[0] = '\0';
- continue;
- }
- /* name: could be text following '# ' */
- /* code: <code>
- * definition follows code until next '<' */
- if (*buf == '#' && buflen > 2) {
- sprintf(name, "%s", buf + 2);
- continue;
- }
- i = 0;
- bufstart = 0;
- while (i < buflen) {
-
- if (buf[i] == '<') {
- /* end of section ? */
- if (code[0] != '\0') {
- G_strip(proj_def);
- /* the descriptive name may be hidden in proj_def as
- * +title=
- * e.g. IGNF */
- fprintf(stdout, "%s|%s|%s\n", code, name, proj_def);
- code[0] = '\0';
- name[0] = '\0';
- proj_def[0] = '\0';
- }
- /* start of section ? */
- bufstart = i + 1;
- j = bufstart;
- while (j < buflen && buf[j] != '>')
- j++;
- if (j < buflen) {
- buf[j] = '\0';
- sprintf(code, "%s", buf + bufstart);
- }
- i = j + 1;
- bufstart = i;
- continue;
- }
-
- if (buf[i] == '#') {
- /* the remaining content of the line could be the name */
- bufstart = i + 1;
- if (bufstart < buflen) {
- sprintf(name, "%s", buf + bufstart);
- G_strip(name);
- }
- i = buflen;
- continue;
- }
- if (code[0] != '\0') {
- char stopchar;
- int proj_len;
- /* inside a section definition */
- /* test for '<' or '#' later on in the line */
- j = bufstart;
- while (j < buflen && buf[j] != '<' && buf[j] != '#')
- j++;
- if (j < buflen) {
- stopchar = buf[j];
- buf[j] = '\0';
- proj_len = strlen(proj_def);
- proj_def[proj_len] = ' ';
- proj_def[proj_len + 1] = '\0';
- strcat(proj_def, buf + bufstart);
- buf[j] = stopchar;
- i = j;
- bufstart = i;
- }
- else {
- proj_len = strlen(proj_def);
- proj_def[proj_len] = ' ';
- proj_def[proj_len + 1] = '\0';
- strcat(proj_def, buf + bufstart);
- i = buflen;
- bufstart = i;
- }
- }
- else
- i++;
- }
- }
- fclose(fp);
- #endif
- }
|