list.c 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173
  1. #include "global.h"
  2. #include <stdlib.h>
  3. #include <unistd.h>
  4. #include <string.h>
  5. #include <grass/gis.h>
  6. #include <grass/raster3d.h>
  7. #include <grass/vector.h>
  8. #include <grass/manage.h>
  9. #include <grass/glocale.h>
  10. static int region_overlaps(const struct Cell_head *, const char *, const char *,
  11. int);
  12. static int compare_elist(const void *, const void *);
  13. void make_list(struct elist **el, int *lcount, int *lalloc,
  14. const struct list *elem, const char *mapset,
  15. const struct Cell_head *window)
  16. {
  17. char path[GPATH_MAX];
  18. const char *element, *alias;
  19. char **list;
  20. int count, i;
  21. int type;
  22. element = elem->element[0];
  23. alias = elem->alias;
  24. G_file_name(path, element, "", mapset);
  25. if (access(path, 0) != 0)
  26. return;
  27. if ((list = G_ls2(path, &count)) == NULL)
  28. return;
  29. if (strcmp(alias, "raster") == 0)
  30. type = TYPE_RAST;
  31. else if (strcmp(alias, "raster_3d") == 0)
  32. type = TYPE_RAST3D;
  33. else if (strcmp(alias, "vector") == 0)
  34. type = TYPE_VECT;
  35. else
  36. type = TYPE_OTHERS;
  37. /* Suppress "... found in more mapsets" warnings from G_find_file2. */
  38. G_suppress_warnings(1);
  39. if (*lcount + count > *lalloc) {
  40. *lalloc = *lcount + count + 10;
  41. *el = G_realloc(*el, *lalloc * sizeof(struct elist));
  42. }
  43. for (i = 0; i < count; i++) {
  44. /* If region= is used, read the map region. */
  45. if (window) {
  46. /* If the map region doesn't overlap with the input region, don't
  47. * print the map. */
  48. if (!region_overlaps(window, list[i], mapset, type))
  49. continue;
  50. }
  51. (*el)[*lcount].type = G_store(alias);
  52. (*el)[*lcount].name = list[i];
  53. (*el)[*lcount].mapset = G_store(mapset);
  54. (*lcount)++;
  55. }
  56. G_suppress_warnings(0);
  57. G_free(list);
  58. }
  59. void print_list(FILE *fp, struct elist *el, int count, const char *separator,
  60. int add_type, int add_mapset)
  61. {
  62. int i;
  63. if (!count)
  64. return;
  65. qsort(el, count, sizeof(struct elist), compare_elist);
  66. for (i = 0; i < count; i++) {
  67. int need_mapset = 0;
  68. if (i != 0)
  69. fprintf(fp, "%s", separator);
  70. if (add_type)
  71. fprintf(fp, "%s/", el[i].type);
  72. fprintf(fp, "%s", el[i].name);
  73. if (!add_mapset) {
  74. if (i + 1 < count)
  75. need_mapset = strcmp(el[i].name, el[i + 1].name) == 0;
  76. if (!need_mapset && i > 0)
  77. need_mapset = strcmp(el[i].name, el[i - 1].name) == 0;
  78. }
  79. if (add_mapset || need_mapset)
  80. fprintf(fp, "@%s", el[i].mapset);
  81. }
  82. fflush(fp);
  83. }
  84. static int region_overlaps(const struct Cell_head *window, const char *name,
  85. const char *mapset, int type)
  86. {
  87. int has_region;
  88. struct Cell_head map_window;
  89. RASTER3D_Region region3d;
  90. struct Map_info Map;
  91. struct bound_box box;
  92. switch (type) {
  93. case TYPE_RAST:
  94. Rast_get_cellhd(name, mapset, &map_window);
  95. has_region = 1;
  96. break;
  97. case TYPE_RAST3D:
  98. if (Rast3d_read_region_map(name, mapset, &region3d) < 0)
  99. G_fatal_error(_("Unable to read header of 3D raster map <%s@%s>"),
  100. name, mapset);
  101. Rast3d_region_to_cell_head(&region3d, &map_window);
  102. has_region = 1;
  103. break;
  104. case TYPE_VECT:
  105. Vect_set_open_level(2);
  106. if (Vect_open_old_head(&Map, name, mapset) < 2)
  107. G_fatal_error(_("Unable to open vector map <%s@%s> on topological level"),
  108. name, mapset);
  109. Vect_get_map_box(&Map, &box);
  110. Vect_close(&Map);
  111. map_window.north = box.N;
  112. map_window.south = box.S;
  113. map_window.west = box.W;
  114. map_window.east = box.E;
  115. has_region = 1;
  116. break;
  117. default:
  118. has_region = 0;
  119. break;
  120. }
  121. /* If an element doesn't have a concept of region at all, return 1 so we
  122. * can always print it. */
  123. if (!has_region)
  124. return 1;
  125. /* If the map region is outside the input region, return 0. Otherwise
  126. * return 1 */
  127. return !(window->north <= map_window.south ||
  128. window->south >= map_window.north ||
  129. window->west >= map_window.east ||
  130. window->east <= map_window.west);
  131. }
  132. static int compare_elist(const void *a, const void *b)
  133. {
  134. struct elist *al = (struct elist *)a;
  135. struct elist *bl = (struct elist *)b;
  136. int ret;
  137. if (!(ret = strcmp(al->type, bl->type))) {
  138. if (!(ret = strcmp(al->name, bl->name)))
  139. ret = strcmp(al->mapset, bl->mapset);
  140. }
  141. return ret;
  142. }