list_codes.c 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195
  1. #include <string.h>
  2. #include <unistd.h>
  3. #include <grass/gis.h>
  4. #include <grass/glocale.h>
  5. #include <grass/config.h>
  6. #ifdef HAVE_PROJ_H
  7. #include <proj.h>
  8. #if PROJ_VERSION_MAJOR >= 6
  9. #define USE_PROJDB
  10. #endif
  11. #else
  12. #include <proj_api.h>
  13. #endif
  14. char *get_authority_names(void)
  15. {
  16. char *authnames;
  17. #ifdef USE_PROJDB
  18. /* PROJ 6 */
  19. int i, len;
  20. PROJ_STRING_LIST authlist = proj_get_authorities_from_database(NULL);
  21. len = 0;
  22. for (i = 0; authlist[i]; i++) {
  23. len += strlen(authlist[i]) + 1;
  24. }
  25. if (len > 0) {
  26. authnames = G_malloc((len + 1) * sizeof(char)); /* \0 */
  27. *authnames = '\0';
  28. for (i = 0; authlist[i]; i++) {
  29. if (i > 0)
  30. strcat(authnames, ",");
  31. strcat(authnames, authlist[i]);
  32. }
  33. }
  34. else {
  35. authnames = G_store("");
  36. }
  37. #else
  38. /* PROJ 4, 5 */
  39. /* there are various init files in share/proj/:
  40. * EPSG,GL27,IGNF,ITRF2000,ITRF2008,ITRF2014,nad27,nad83,esri
  41. * but they have different formats: bothering only with EPSG here */
  42. authnames = G_store("EPSG");
  43. #endif
  44. return authnames;
  45. }
  46. void list_codes(char *authname)
  47. {
  48. #ifdef USE_PROJDB
  49. /* PROJ 6+ */
  50. int i, crs_cnt;
  51. PROJ_CRS_INFO **proj_crs_info;
  52. crs_cnt = 0;
  53. proj_crs_info = proj_get_crs_info_list_from_database(NULL,
  54. authname, NULL, &crs_cnt);
  55. if (crs_cnt < 1)
  56. G_fatal_error(_("No codes found for authority %s"),
  57. authname);
  58. for (i = 0; i < crs_cnt; i++) {
  59. const char *proj_definition;
  60. char emptystr;
  61. PJ *pj;
  62. emptystr = '\0';
  63. pj = proj_create_from_database(NULL,
  64. proj_crs_info[i]->auth_name,
  65. proj_crs_info[i]->code,
  66. PJ_CATEGORY_CRS,
  67. 0, NULL);
  68. proj_definition = proj_as_proj_string(NULL, pj, PJ_PROJ_5, NULL);
  69. if (!proj_definition) {
  70. /* what to do with a CRS without proj string ? */
  71. G_debug(1, "No proj string for %s:%s",
  72. proj_crs_info[i]->auth_name,
  73. proj_crs_info[i]->code);
  74. proj_definition = &emptystr;
  75. }
  76. if (proj_definition) {
  77. fprintf(stdout, "%s|%s|%s\n", proj_crs_info[i]->code,
  78. proj_crs_info[i]->name,
  79. proj_definition);
  80. }
  81. proj_destroy(pj);
  82. }
  83. #else
  84. char pathname[GPATH_MAX];
  85. char code[GNAME_MAX], name[GNAME_MAX], proj_def[GNAME_MAX];
  86. FILE *fp;
  87. char buf[4096];
  88. int line;
  89. #ifdef HAVE_PROJ_H
  90. /* PROJ 5 */
  91. PJ_INIT_INFO init_info;
  92. if (G_strcasecmp(authname, "EPSG") == 0)
  93. authname = "epsg";
  94. init_info = proj_init_info(authname);
  95. sprintf(pathname, init_info.filename);
  96. if (access(pathname, F_OK) != 0)
  97. G_fatal_error(_("Unable to find init file %s"), authname);
  98. #else
  99. /* PROJ 4 */
  100. /* can't use pj_find_file() from the old proj api
  101. * because it does not exist in PROJ 4 */
  102. char *grass_proj_share;
  103. authname = listcodes->answer;
  104. if (G_strcasecmp(authname, "EPSG") == 0)
  105. authname = "epsg";
  106. grass_proj_share = getenv("GRASS_PROJSHARE");
  107. if (!grass_proj_share)
  108. G_fatal_error(_("Environment variable GRASS_PROJSHARE is not set"));
  109. sprintf(pathname, "%s/%s", grass_proj_share, authname);
  110. G_convert_dirseps_to_host(pathname);
  111. #endif
  112. /* PROJ 4 / 5 */
  113. /* the init files do not have a common structure, thus restrict to epsg
  114. * see pj_init.c get_init_string() in PROJ 4 / 5 for a
  115. * generic init file parser, however without descriptive name */
  116. if (strcmp(authname, "epsg") != 0)
  117. G_fatal_error(_("Only epsg file is currently supported"));
  118. /* open the init file */
  119. fp = fopen(pathname, "r");
  120. if (!fp) {
  121. G_fatal_error(_("Unable to open init file <%s>"), authname);
  122. }
  123. name[0] = '\0';
  124. /* print list of codes, names, definitions */
  125. for (line = 1; G_getl2(buf, sizeof(buf), fp); line++) {
  126. int buflen;
  127. G_strip(buf);
  128. buflen = strlen(buf);
  129. if (*buf == '\0' ||
  130. (buflen >= 10 && strncmp(buf, "<metadata>", 10) == 0)) {
  131. name[0] = '\0';
  132. continue;
  133. }
  134. if (strncmp(buf, "<metadata>", strlen("<metadata>")) == 0)
  135. continue;
  136. /* name: line starts with '# ' */
  137. /* code and definition in next line */
  138. if (*buf == '#' && buflen > 2) {
  139. sprintf(name, buf + 2);
  140. continue;
  141. }
  142. if (*buf == '<') {
  143. int i, j;
  144. i = 0;
  145. while (i < buflen && buf[i] != '>')
  146. i++;
  147. buf[i] = '\0';
  148. sprintf(code, buf + 1);
  149. i++;
  150. j = i;
  151. while (i < buflen && buf[i] != '<')
  152. i++;
  153. if (i < buflen && buf[i] == '<')
  154. buf[i] = '\0';
  155. sprintf(proj_def, buf + j);
  156. G_strip(proj_def);
  157. fprintf(stdout, "%s|%s|%s\n", code, name, proj_def);
  158. name[0] = '\0';
  159. }
  160. }
  161. fclose(fp);
  162. #endif
  163. }