[GRASS-SVN] r61039 - grass/branches/releasebranch_7_0/general/g.mlist
svn_grass at osgeo.org
svn_grass at osgeo.org
Sat Jun 28 16:00:29 PDT 2014
Author: hcho
Date: 2014-06-28 16:00:29 -0700 (Sat, 28 Jun 2014)
New Revision: 61039
Modified:
grass/branches/releasebranch_7_0/general/g.mlist/Makefile
grass/branches/releasebranch_7_0/general/g.mlist/main.c
Log:
g.mlist: backport from trunk
Modified: grass/branches/releasebranch_7_0/general/g.mlist/Makefile
===================================================================
--- grass/branches/releasebranch_7_0/general/g.mlist/Makefile 2014-06-28 22:18:06 UTC (rev 61038)
+++ grass/branches/releasebranch_7_0/general/g.mlist/Makefile 2014-06-28 23:00:29 UTC (rev 61039)
@@ -2,8 +2,10 @@
PGM = g.mlist
-LIBES = $(MANAGELIB) $(GISLIB)
-DEPENDENCIES = $(MANAGEDEP) $(GISDEP)
+LIBES = $(MANAGELIB) $(GISLIB) $(RASTERLIB) $(RASTER3DLIB) $(VECTORLIB)
+DEPENDENCIES = $(MANAGEDEP) $(GISDEP) $(RASTERDEP) $(RASTER3DDEP) $(VECTORDEP)
+EXTRA_INC = $(VECT_INC)
+EXTRA_CFLAGS = $(VECT_CFLAGS)
include $(MODULE_TOPDIR)/include/Make/Module.make
Modified: grass/branches/releasebranch_7_0/general/g.mlist/main.c
===================================================================
--- grass/branches/releasebranch_7_0/general/g.mlist/main.c 2014-06-28 22:18:06 UTC (rev 61038)
+++ grass/branches/releasebranch_7_0/general/g.mlist/main.c 2014-06-28 23:00:29 UTC (rev 61039)
@@ -21,14 +21,25 @@
#include <unistd.h>
#include <string.h>
#include <grass/gis.h>
+#include <grass/raster3d.h>
+#include <grass/vector.h>
#include <grass/manage.h>
#include <grass/glocale.h>
#include <grass/spawn.h>
+enum {
+ TYPE_RAST,
+ TYPE_RAST3D,
+ TYPE_VECT,
+ TYPE_3DVIEW,
+ TYPE_OTHERS
+};
+
static int any = 0;
-static void make_list(FILE *, const struct list *, const char *, const char *,
- int, int, int);
+static void make_list(FILE *, const struct list *, const char *,
+ const char *, int, int, struct Cell_head *);
+static int region_overlaps(struct Cell_head *, const char *, const char *, int);
int main(int argc, char *argv[])
{
@@ -40,6 +51,7 @@
struct Option *exclude;
struct Option *separator;
struct Option *mapset;
+ struct Option *region;
struct Option *output;
} opt;
struct
@@ -51,11 +63,14 @@
struct Flag *pretty;
struct Flag *full;
} flag;
- int i, n, all, num_types, nlist;
- void *filter = NULL, *exclude = NULL;
+ int i, j, n, all, num_types, nlist;
+ void *filter, *exclude;
+ struct Popen pager;
FILE *fp;
const char *mapset;
char *separator;
+ int use_region;
+ struct Cell_head window;
G_gisinit(argv[0]);
@@ -64,8 +79,8 @@
G_add_keyword(_("map management"));
G_add_keyword(_("list"));
module->description =
- _("Lists available GRASS data base files "
- "of the user-specified data type optionally using the search pattern.");
+ _("Lists available GRASS data base files of "
+ "the user-specified data type optionally using the search pattern.");
M_read_list(FALSE, &nlist);
@@ -73,7 +88,7 @@
opt.type->multiple = YES;
opt.type->options = M_get_options(TRUE);
opt.type->descriptions = M_get_option_desc(TRUE);
-
+
opt.pattern = G_define_option();
opt.pattern->key = "pattern";
opt.pattern->type = TYPE_STRING;
@@ -91,12 +106,19 @@
opt.exclude->guisection = _("Pattern");
opt.mapset = G_define_standard_option(G_OPT_M_MAPSET);
+ opt.mapset->multiple = YES;
opt.mapset->label =
_("Name of mapset to list (default: current search path)");
-
+ opt.mapset->description =
+ _("'.' for current mapset; '*' for all mapsets in location");
opt.separator = G_define_standard_option(G_OPT_F_SEP);
opt.separator->answer = "newline";
+ opt.region = G_define_standard_option(G_OPT_M_REGION);
+ opt.region->label = _("Name of saved region for map search (default: not restricted)");
+ opt.region->description =
+ _("'.' for current region; '*' for default region");
+
opt.output = G_define_standard_option(G_OPT_F_OUTPUT);
opt.output->required = NO;
opt.output->label = _("Name for output file");
@@ -118,7 +140,7 @@
flag.type->key = 't';
flag.type->description = _("Print data types");
flag.type->guisection = _("Print");
-
+
flag.mapset = G_define_flag();
flag.mapset->key = 'm';
flag.mapset->description = _("Print fully-qualified map names (including mapsets)");
@@ -137,46 +159,97 @@
if (G_parser(argc, argv))
exit(EXIT_FAILURE);
- if (opt.output->answer && flag.pretty->answer)
- G_fatal_error(_("output= and -p are mutually exclusive"));
+ if ((flag.pretty->answer || flag.full->answer) && opt.output->answer)
+ G_fatal_error(_("-%c/-%c and %s= are mutually exclusive"),
+ flag.pretty->key, flag.full->key, opt.output->key);
- if (opt.output->answer && flag.full->answer)
- G_fatal_error(_("output= and -f are mutually exclusive"));
+ if ((flag.pretty->answer || flag.full->answer) && opt.region->answer)
+ G_fatal_error(_("-%c/-%c and %s= are mutually exclusive"),
+ flag.pretty->key, flag.full->key, opt.region->key);
- if (flag.type->answer && flag.pretty->answer)
- G_fatal_error(_("-t and -p are mutually exclusive"));
+ if ((flag.pretty->answer || flag.full->answer) &&
+ (flag.mapset->answer || flag.type->answer))
+ G_fatal_error(_("-%c/-%c and -%c/-%c are mutually exclusive"),
+ flag.pretty->key, flag.full->key,
+ flag.mapset->key, flag.type->key);
- if (flag.type->answer && flag.full->answer)
- G_fatal_error(_("-t and -f are mutually exclusive"));
+ if (flag.pretty->answer && flag.full->answer)
+ G_fatal_error(_("-%c and -%c are mutually exclusive"),
+ flag.pretty->key, flag.full->key);
- if (flag.full->answer && flag.pretty->answer)
- G_fatal_error(_("-f and -p are mutually exclusive"));
-
if (flag.regex->answer && flag.extended->answer)
- G_fatal_error(_("-r and -e are mutually exclusive"));
+ G_fatal_error(_("-%c and -%c are mutually exclusive"),
+ flag.regex->key, flag.extended->key);
if (opt.pattern->answer) {
if (flag.regex->answer || flag.extended->answer)
- filter = G_ls_regex_filter(opt.pattern->answer, 0, (int) flag.extended->answer);
- else
- filter = G_ls_glob_filter(opt.pattern->answer, 0);
+ filter = G_ls_regex_filter(opt.pattern->answer, 0,
+ (int)flag.extended->answer);
+ else {
+ /* handle individual map names */
+ if (strchr(opt.pattern->answer, ',')) {
+ char *pattern;
+
+ pattern = (char *)G_malloc(strlen(opt.pattern->answer) + 3);
+ sprintf(pattern, "{%s}", opt.pattern->answer);
+
+ filter = G_ls_glob_filter(pattern, 0);
+ }
+ else
+ filter = G_ls_glob_filter(opt.pattern->answer, 0);
+ }
+ if (!filter)
+ G_fatal_error(_("Unable to compile pattern <%s>"),
+ opt.pattern->answer);
}
+ else
+ filter = NULL;
if (opt.exclude->answer) {
if (flag.regex->answer || flag.extended->answer)
- exclude = G_ls_regex_filter(opt.exclude->answer, 1, (int) flag.extended->answer);
- else
- exclude = G_ls_glob_filter(opt.exclude->answer, 1);
+ exclude = G_ls_regex_filter(opt.exclude->answer, 1,
+ (int)flag.extended->answer);
+ else {
+ /* handle individual map names */
+ if (strchr(opt.exclude->answer, ',')) {
+ char *pattern;
+
+ pattern = (char *)G_malloc(strlen(opt.exclude->answer) + 3);
+ sprintf(pattern, "{%s}", opt.exclude->answer);
+
+ exclude = G_ls_glob_filter(pattern, 1);
+ }
+ else
+ exclude = G_ls_glob_filter(opt.exclude->answer, 1);
+ }
+ if (!exclude)
+ G_fatal_error(_("Unable to compile pattern <%s>"),
+ opt.exclude->answer);
}
+ else
+ exclude = NULL;
separator = G_option_to_separator(opt.separator);
- fp = G_open_option_file(opt.output);
- if ((mapset = opt.mapset->answer) == NULL)
- mapset = "";
- else if (strcmp(mapset, ".") == 0)
- mapset = G_mapset();
+ if (opt.region->answer) {
+ use_region = 1;
+ if (strcmp(opt.region->answer, "*") == 0)
+ G_get_default_window(&window);
+ else if (strcmp(opt.region->answer, ".") == 0)
+ G_get_window(&window);
+ else {
+ char name[GNAME_MAX], mapset[GMAPSET_MAX];
+
+ if (G_name_is_fully_qualified(opt.region->answer, name, mapset))
+ G__get_window(&window, "windows", name, mapset);
+ else
+ G__get_window(&window, "windows", opt.region->answer, "");
+ }
+ }
+ else
+ use_region = 0;
+
for (i = 0; opt.type->answers[i]; i++) {
if (strcmp(opt.type->answers[i], "all") == 0)
break;
@@ -190,11 +263,37 @@
num_types = i;
}
+ if (opt.mapset->answers && opt.mapset->answers[0]) {
+ G_create_alt_search_path();
+ for (i = 0; (mapset = opt.mapset->answers[i]); i++) {
+ if (strcmp(mapset, "*") == 0) {
+ /* all mapsets from current location */
+ char **ms;
+
+ ms = G_get_available_mapsets();
+ for (j = 0; (mapset = ms[j]); j++)
+ G_add_mapset_to_search_path(mapset);
+ continue;
+ }
+ else if (strcmp(mapset, ".") == 0)
+ mapset = G_mapset();
+ else if (G__mapset_permissions(mapset) == -1)
+ G_fatal_error(_("Mapset <%s> does not exist"), mapset);
+ G_add_mapset_to_search_path(mapset);
+ }
+ }
+
+ if (flag.pretty->answer || flag.full->answer) {
+ fp = G_open_pager(&pager);
+ dup2(fileno(fp), STDOUT_FILENO);
+ }
+ else
+ fp = G_open_option_file(opt.output);
+
for (i = 0; i < num_types; i++) {
const struct list *elem;
n = all ? i : M_get_element(opt.type->answers[i]);
-
elem = M_get_list(n);
if (flag.full->answer) {
@@ -204,23 +303,30 @@
G_debug(3, "lister CMD: %s", lister);
- if (access(lister, 1) == 0) { /* execute permission? */
+ if (access(lister, X_OK) == 0) /* execute permission? */
G_spawn(lister, lister, mapset, NULL);
- continue;
- }
+ else
+ M_do_list(n, "");
}
else if (flag.pretty->answer)
- G_list_element(elem->element[0], elem->alias, mapset, NULL);
- else
- make_list(fp, elem, mapset, separator, flag.type->answer,
- flag.mapset->answer, mapset && *mapset);
+ M_do_list(n, "");
+ else {
+ for (j = 0; (mapset = G_get_mapset_name(j)); j++)
+ make_list(fp, elem, mapset, separator, flag.type->answer,
+ flag.mapset->answer, use_region ? &window : NULL);
+ }
}
- if (any)
- fprintf(fp, "\n");
+ if (flag.pretty->answer || flag.full->answer) {
+ fclose(stdout);
+ G_close_pager(&pager);
+ }
+ else {
+ if (any)
+ fprintf(fp, "\n");
+ G_close_option_file(fp);
+ }
- G_close_option_file(fp);
-
if (filter)
G_free_ls_filter(filter);
@@ -232,22 +338,17 @@
static void make_list(FILE *fp, const struct list *elem, const char *mapset,
const char *separator, int add_type, int add_mapset,
- int single_mapset)
+ struct Cell_head *window)
{
+ static int first_mapset = 1;
char path[GPATH_MAX];
- const char *element = elem->element[0];
- const char *alias = elem->alias;
+ const char *element, *alias;
char **list;
- int count;
- int i;
+ int count, first, i;
+ int type;
- if (!mapset || !*mapset) {
- int n;
- for (n = 0; mapset = G_get_mapset_name(n), mapset; n++)
- make_list(fp, elem, mapset, separator, add_type, add_mapset,
- n == 0);
- return;
- }
+ element = elem->element[0];
+ alias = elem->alias;
G_file_name(path, element, "", mapset);
if (access(path, 0) != 0)
@@ -256,29 +357,52 @@
if ((list = G__ls(path, &count)) == NULL)
return;
- if (count > 0) {
- if (any)
- fprintf(fp, "%s", separator);
- if (fp == stdout)
- G_message(_("%s available in mapset <%s>:"), elem->text, mapset);
- }
+ if (strcmp(alias, "rast") == 0)
+ type = TYPE_RAST;
+ else if (strcmp(alias, "rast3d") == 0)
+ type = TYPE_RAST3D;
+ else if (strcmp(alias, "vect") == 0)
+ type = TYPE_VECT;
+ else if (strcmp(alias, "3dview") == 0)
+ type = TYPE_3DVIEW;
+ else
+ type = TYPE_OTHERS;
/* Suppress "... found in more mapsets" warnings from G_find_file2. */
G_suppress_warnings(1);
+ first = 1;
for (i = 0; i < count; i++) {
char *name = list[i];
int need_mapset = 0;
+ /* If region= is used, read the map region. */
+ if (window) {
+ /* If the map region doesn't overlap with the input region, don't
+ * print the map. */
+ if (!region_overlaps(window, name, mapset, type))
+ continue;
+ }
+
+ if (first) {
+ first = 0;
+
+ if (any)
+ fprintf(fp, "%s", separator);
+ if (fp == stdout && isatty(STDOUT_FILENO))
+ G_message(_("%s available in mapset <%s>:"),
+ elem->text, mapset);
+ }
+
if (any && i != 0)
fprintf(fp, "%s", separator);
-
+
if (add_type)
fprintf(fp, "%s/", alias);
fprintf(fp, "%s", name);
- if (!add_mapset && !single_mapset) {
+ if (!add_mapset && !first_mapset) {
const char *mapset2 = G_find_file2(element, name, "");
if (mapset2)
need_mapset = strcmp(mapset, mapset2) != 0;
@@ -293,7 +417,80 @@
G_suppress_warnings(0);
fflush(fp);
-
+
G_free(list);
+
+ first_mapset = 0;
}
+static int region_overlaps(struct Cell_head *window, const char *name,
+ const char *mapset, int type)
+{
+ int has_region;
+ struct Cell_head map_window;
+ RASTER3D_Region region3d;
+ struct Map_info Map;
+ struct bound_box box;
+ int ret;
+ struct G_3dview view3d;
+
+ switch (type) {
+ case TYPE_RAST:
+ Rast_get_cellhd(name, mapset, &map_window);
+ has_region = 1;
+ break;
+ case TYPE_RAST3D:
+ if (Rast3d_read_region_map(name, mapset, ®ion3d) < 0)
+ G_fatal_error(_("Unable to read header of 3D raster map <%s@%s>"),
+ name, mapset);
+ Rast3d_region_to_cell_head(®ion3d, &map_window);
+ has_region = 1;
+ break;
+ case TYPE_VECT:
+ Vect_set_open_level(2);
+ if (Vect_open_old(&Map, name, mapset) < 2)
+ G_fatal_error(_("Unable to open vector map <%s@%s> on topological level"),
+ name, mapset);
+ Vect_get_map_box(&Map, &box);
+ Vect_close(&Map);
+
+ map_window.north = box.N;
+ map_window.south = box.S;
+ map_window.west = box.W;
+ map_window.east = box.E;
+ has_region = 1;
+ break;
+ case TYPE_3DVIEW:
+ if ((ret = G_get_3dview(name, mapset, &view3d)) < 0)
+ G_fatal_error(_("Unable to read 3dview file <%s@%s>"),
+ name, mapset);
+ if (ret == 0) {
+ G_warning(_("No region support in an old 3dview file <%s@%s>. Listing anyway"),
+ name, mapset);
+ has_region = 0;
+ }
+ else {
+ map_window.north = view3d.vwin.north;
+ map_window.south = view3d.vwin.south;
+ map_window.west = view3d.vwin.west;
+ map_window.east = view3d.vwin.east;
+ has_region = 1;
+ }
+ break;
+ default:
+ has_region = 0;
+ break;
+ }
+
+ /* If an element doesn't have a concept of region at all, return 1 so we
+ * can always print it. */
+ if (!has_region)
+ return 1;
+
+ /* If the map region is outside the input region, return 0. Otherwise
+ * return 1 */
+ return !(window->north <= map_window.south ||
+ window->south >= map_window.north ||
+ window->west >= map_window.east ||
+ window->east <= map_window.west);
+}
More information about the grass-commit
mailing list