[GRASS-SVN] r47790 - grass/trunk/vector/v.extract
svn_grass at osgeo.org
svn_grass at osgeo.org
Sun Aug 21 07:01:07 EDT 2011
Author: martinl
Date: 2011-08-21 04:01:07 -0700 (Sun, 21 Aug 2011)
New Revision: 47790
Added:
grass/trunk/vector/v.extract/copy_tab.c
grass/trunk/vector/v.extract/local_proto.h
Modified:
grass/trunk/vector/v.extract/extract.c
grass/trunk/vector/v.extract/main.c
Log:
v.extract: major update for G7
experimental support for OGR write access
Added: grass/trunk/vector/v.extract/copy_tab.c
===================================================================
--- grass/trunk/vector/v.extract/copy_tab.c (rev 0)
+++ grass/trunk/vector/v.extract/copy_tab.c 2011-08-21 11:01:07 UTC (rev 47790)
@@ -0,0 +1,111 @@
+#include <grass/gis.h>
+#include <grass/vector.h>
+#include <grass/dbmi.h>
+#include <grass/glocale.h>
+
+#include "local_proto.h"
+
+void copy_tabs(const struct Map_info *In, int field, int new_cat,
+ struct Map_info *Out)
+{
+ int nlines, line, i;
+ int ttype, ntabs;
+ int **ocats, *nocats, nfields, *fields;
+
+ struct field_info *IFi, *OFi;
+ struct line_cats *Cats;
+
+ ntabs = 0;
+
+ /* Collect list of output cats */
+ Cats = Vect_new_cats_struct();
+ nfields = Vect_cidx_get_num_fields(Out);
+ ocats = (int **)G_malloc(nfields * sizeof(int *));
+ nocats = (int *)G_malloc(nfields * sizeof(int));
+ fields = (int *)G_malloc(nfields * sizeof(int));
+ for (i = 0; i < nfields; i++) {
+ nocats[i] = 0;
+ ocats[i] =
+ (int *)G_malloc(Vect_cidx_get_num_cats_by_index(Out, i) *
+ sizeof(int));
+ fields[i] = Vect_cidx_get_field_number(Out, i);
+ }
+
+ nlines = Vect_get_num_lines(Out);
+ for (line = 1; line <= nlines; line++) {
+ Vect_read_line(Out, NULL, Cats, line);
+
+ for (i = 0; i < Cats->n_cats; i++) {
+ int f, j;
+
+ for (j = 0; j < nfields; j++) { /* find field */
+ if (fields[j] == Cats->field[i]) {
+ f = j;
+ break;
+ }
+ }
+ ocats[f][nocats[f]] = Cats->cat[i];
+ nocats[f]++;
+ }
+ }
+
+ /* Copy tables */
+ G_message(_("Writing attributes..."));
+
+ /* Number of output tabs */
+ for (i = 0; i < Vect_get_num_dblinks(In); i++) {
+ int j, f = -1;
+
+ IFi = Vect_get_dblink(In, i);
+
+ for (j = 0; j < nfields; j++) { /* find field */
+ if (fields[j] == IFi->number) {
+ f = j;
+ break;
+ }
+ }
+ if (f >= 0 && nocats[f] > 0)
+ ntabs++;
+ }
+
+ if (ntabs > 1)
+ ttype = GV_MTABLE;
+ else
+ ttype = GV_1TABLE;
+
+ for (i = 0; i < nfields; i++) {
+ int ret;
+
+ if (fields[i] == 0)
+ continue;
+ if (nocats[i] == 0)
+ continue;
+ if (fields[i] == field && new_cat != -1)
+ continue;
+
+ G_verbose_message(_("Writting attributes for layer %d"), fields[i]);
+
+ /* Make a list of categories */
+ IFi = Vect_get_field(In, fields[i]);
+ if (!IFi) { /* no table */
+ G_message(_("No attribute table for layer %d"), fields[i]);
+ continue;
+ }
+
+ OFi = Vect_default_field_info(Out, IFi->number, NULL, ttype);
+
+ ret = db_copy_table_by_ints(IFi->driver, IFi->database, IFi->table,
+ OFi->driver,
+ Vect_subst_var(OFi->database, Out),
+ OFi->table, IFi->key, ocats[i],
+ nocats[i]);
+
+ if (ret == DB_FAILED) {
+ G_warning(_("Unable to copy table <%s>"), IFi->table);
+ }
+ else {
+ Vect_map_add_dblink(Out, OFi->number, OFi->name, OFi->table,
+ IFi->key, OFi->database, OFi->driver);
+ }
+ }
+}
Property changes on: grass/trunk/vector/v.extract/copy_tab.c
___________________________________________________________________
Added: svn:mime-type
+ text/x-csrc
Added: svn:eol-style
+ native
Modified: grass/trunk/vector/v.extract/extract.c
===================================================================
--- grass/trunk/vector/v.extract/extract.c 2011-08-21 10:52:16 UTC (rev 47789)
+++ grass/trunk/vector/v.extract/extract.c 2011-08-21 11:01:07 UTC (rev 47790)
@@ -29,7 +29,7 @@
}
/* check if cat is in list */
-int in_list(int cat)
+static int in_list(int cat)
{
if (bsearch(&cat, cats_array, ncats_array, sizeof(int), cmp))
return 1;
@@ -38,8 +38,8 @@
}
/* output reclass cats */
-void extract_cats(struct line_cats *Cats, int type_only, int field, int new,
- int reverse)
+static void extract_cats(struct line_cats *Cats, int type_only, int field, int new,
+ int reverse)
{
int i, tmp;
static struct line_cats *TCats = NULL;
@@ -105,8 +105,8 @@
}
/* check if output cats of left and right area match */
-int areas_new_cats_match(struct Map_info *In, int area1, int area2,
- int type_only, int field, int new, int reverse)
+static int areas_new_cats_match(struct Map_info *In, int area1, int area2,
+ int type_only, int field, int new, int reverse)
{
int i, j, found;
int centroid1, centroid2;
@@ -157,10 +157,9 @@
return 1;
}
-int
-xtract_line(int num_index, int *num_array, struct Map_info *In,
- struct Map_info *Out, int new, int select_type, int dissolve,
- int field, int type_only, int reverse)
+int extract_line(int num_index, int *num_array, struct Map_info *In,
+ struct Map_info *Out, int new, int select_type, int dissolve,
+ int field, int type_only, int reverse)
{
int line, nlines;
struct line_pnts *Points;
@@ -352,6 +351,7 @@
}
} /* end lines section */
-
- return (0);
+ G_percent(1, 1, 1);
+
+ return 0;
}
Added: grass/trunk/vector/v.extract/local_proto.h
===================================================================
--- grass/trunk/vector/v.extract/local_proto.h (rev 0)
+++ grass/trunk/vector/v.extract/local_proto.h 2011-08-21 11:01:07 UTC (rev 47790)
@@ -0,0 +1,9 @@
+/* copy_tab.c */
+void copy_tabs(const struct Map_info *, int, int,
+ struct Map_info *);
+
+/* extract.c */
+int cmp(const void *, const void *);
+int extract_line(int, int *, struct Map_info *,
+ struct Map_info *, int, int, int,
+ int, int, int);
Property changes on: grass/trunk/vector/v.extract/local_proto.h
___________________________________________________________________
Added: svn:mime-type
+ text/x-chdr
Added: svn:eol-style
+ native
Modified: grass/trunk/vector/v.extract/main.c
===================================================================
--- grass/trunk/vector/v.extract/main.c 2011-08-21 10:52:16 UTC (rev 47789)
+++ grass/trunk/vector/v.extract/main.c 2011-08-21 11:01:07 UTC (rev 47790)
@@ -4,19 +4,18 @@
* MODULE: v.extract
*
* AUTHOR(S): R.L.Glenn , Soil Conservation Service, USDA
- * update to 5.7: Radim Blazek
+ * Updated for 5.7 by Radim Blazek
+ * Updated for 7.0 by Martin Landa <landa.martin gmail.com>
*
- * PURPOSE: Provides a means of generating vector (digit) files
- * from an existing vector maplayer. Selects all vector
- * boundaries for 1 or several areas of a list of
- * user provided categories.
+ * PURPOSE: Selects vector features from an existing vector map and
+ * creates a new vector map containing only the selected
+ * features.
*
- * COPYRIGHT: (C) 2002-2009 by the GRASS Development Team
+ * COPYRIGHT: (C) 2002-2009, 2011 by the GRASS Development Team
*
- * This program is free software under the
- * GNU General Public License (>=v2).
- * Read the file COPYING that comes with GRASS
- * for details.
+ * This program is free software under the GNU General
+ * Public License (>=v2). Read the file COPYING that
+ * comes with GRASS for details.
*
* TODO: - fix white space problems for file= option
****************************************************************/
@@ -28,62 +27,50 @@
#include <search.h>
#include <sys/types.h>
#include <unistd.h>
+
#include <grass/gis.h>
#include <grass/vector.h>
#include <grass/dbmi.h>
#include <grass/gmath.h>
#include <grass/glocale.h>
+#include "local_proto.h"
+
static int *cat_array, cat_count, cat_size;
-int scan_cats(char *, int *, int *);
-int xtract_line(int, int[], struct Map_info *, struct Map_info *, int, int,
- int, int, int, int);
-static void add_cat(int x)
-{
- G_debug(2, "add_cat %d", x);
+static int scan_cats(char *, int *, int *);
+static void add_cat(int);
- if (cat_count >= cat_size) {
- cat_size = (cat_size < 1000) ? 1000 : cat_size * 2;
- cat_array = G_realloc(cat_array, cat_size * sizeof(int));
- }
-
- cat_array[cat_count++] = x;
-}
-
-/* Comparison function for *search */
-static int cmp(const void *pa, const void *pb)
-{
- int *p1 = (int *)pa;
- int *p2 = (int *)pb;
-
- if (*p1 < *p2)
- return -1;
- if (*p1 > *p2)
- return 1;
- return 0;
-}
-
int main(int argc, char **argv)
{
- int i, new_cat, type, ncats, *cats, c;
- int **ocats, *nocats, nfields, *fields;
- int field;
- int dissolve = 0, x, y, type_only;
+ int i, new_cat, type, ncats, *cats, c, is_ogr;
+ int field, dissolve, x, y, type_only;
char buffr[1024], text[80];
char *input, *output;
+
+ FILE *in;
+
struct GModule *module;
- struct Option *inopt, *outopt, *fileopt, *newopt, *typopt, *listopt,
- *fieldopt, *whereopt, *nrandopt;
- struct Flag *t_flag, *d_flag, *r_flag;
+ struct {
+ struct Option *input, *output, *file, *new, *type, *list,
+ *field, *where, *nrand;
+ } opt;
+ struct {
+ struct Flag *t, *d, *r;
+ } flag;
+
struct Map_info In, Out;
struct field_info *Fi;
- FILE *in;
+
dbDriver *driver;
- struct line_cats *Cats;
+
struct Cat_index *ci;
- int ucat_count, *ucat_array = NULL, prnd, seed, nrandom, nfeatures;
+
+ int ucat_count, *ucat_array, prnd, seed, nrandom, nfeatures;
+ Fi = NULL;
+ ucat_array = NULL;
+
G_gisinit(argv[0]);
/* set up the options and flags for the command line parser */
@@ -91,160 +78,159 @@
G_add_keyword(_("vector"));
G_add_keyword(_("extract"));
module->description =
- _("Selects vector objects from an existing vector map and "
- "creates a new map containing only the selected objects.");
+ _("Selects vector features from an existing vector map and "
+ "creates a new vector map containing only the selected features.");
- d_flag = G_define_flag();
- d_flag->key = 'd';
- d_flag->description = _("Dissolve common boundaries (default is no)");
+ flag.d = G_define_flag();
+ flag.d->key = 'd';
+ flag.d->description = _("Dissolve common boundaries (default is no)");
- t_flag = G_define_flag();
- t_flag->key = 't';
- t_flag->description = _("Do not copy table (see also 'new' parameter)");
+ flag.t = G_define_flag();
+ flag.t->key = 't';
+ flag.t->description = _("Do not copy attributes (see also 'new' parameter)");
+ flag.t->guisection = _("Attributes");
- r_flag = G_define_flag();
- r_flag->key = 'r';
- r_flag->description = _("Reverse selection");
- r_flag->guisection = _("Selection");
+ flag.r = G_define_flag();
+ flag.r->key = 'r';
+ flag.r->description = _("Reverse selection");
+ flag.r->guisection = _("Selection");
- inopt = G_define_standard_option(G_OPT_V_INPUT);
+ opt.input = G_define_standard_option(G_OPT_V_INPUT);
- fieldopt = G_define_standard_option(G_OPT_V_FIELD);
- fieldopt->guisection = _("Selection");
+ opt.field = G_define_standard_option(G_OPT_V_FIELD);
+ opt.field->guisection = _("Selection");
- typopt = G_define_standard_option(G_OPT_V_TYPE);
- typopt->answer = "point,line,boundary,centroid,area,face";
- typopt->options = "point,line,boundary,centroid,area,face";
- typopt->label = _("Types to be extracted");
- typopt->guisection = _("Selection");
+ opt.type = G_define_standard_option(G_OPT_V_TYPE);
+ opt.type->answer = "point,line,boundary,centroid,area,face";
+ opt.type->options = "point,line,boundary,centroid,area,face";
+ opt.type->label = _("Types to be extracted");
+ opt.type->guisection = _("Selection");
- listopt = G_define_standard_option(G_OPT_V_CATS);
- listopt->key = "list";
- listopt->guisection = _("Selection");
+ opt.list = G_define_standard_option(G_OPT_V_CATS);
+ opt.list->guisection = _("Selection");
- whereopt = G_define_standard_option(G_OPT_DB_WHERE);
- whereopt->guisection = _("Selection");
+ opt.where = G_define_standard_option(G_OPT_DB_WHERE);
+ opt.where->guisection = _("Selection");
- outopt = G_define_standard_option(G_OPT_V_OUTPUT);
+ opt.output = G_define_standard_option(G_OPT_V_OUTPUT);
- fileopt = G_define_standard_option(G_OPT_F_INPUT);
- fileopt->key = "file";
- fileopt->required = NO;
- fileopt->label =
+ opt.file = G_define_standard_option(G_OPT_F_INPUT);
+ opt.file->key = "file";
+ opt.file->required = NO;
+ opt.file->label =
_("Input text file with category numbers/number ranges to be extracted");
- fileopt->description = _("If '-' given reads from standard input");
- fileopt->guisection = _("Selection");
+ opt.file->description = _("If '-' given reads from standard input");
+ opt.file->guisection = _("Selection");
- nrandopt = G_define_option();
- nrandopt->key = "random";
- nrandopt->type = TYPE_INTEGER;
- nrandopt->required = NO;
- nrandopt->label =
+ opt.nrand = G_define_option();
+ opt.nrand->key = "random";
+ opt.nrand->type = TYPE_INTEGER;
+ opt.nrand->required = NO;
+ opt.nrand->label =
_("Number of random categories matching vector objects to extract");
- nrandopt->description =
+ opt.nrand->description =
_("Number must be smaller than unique cat count in layer");
- nrandopt->guisection = _("Selection");
+ opt.nrand->guisection = _("Selection");
- newopt = G_define_option();
- newopt->key = "new";
- newopt->type = TYPE_INTEGER;
- newopt->required = NO;
- newopt->answer = "-1";
- newopt->label =
- _("Enter -1 to keep original categories or the desired NEW category value");
- newopt->description = _("If new >= 0, table is not copied");
+ opt.new = G_define_option();
+ opt.new->key = "new";
+ opt.new->type = TYPE_INTEGER;
+ opt.new->required = NO;
+ opt.new->answer = "-1";
+ opt.new->label = _("Desired new category value "
+ "(enter -1 to keep original categories)");
+ opt.new->description = _("If new >= 0, attributes is not copied");
+ opt.new->guisection = _("Attributes");
- /* heeeerrrrrre's the PARSER */
if (G_parser(argc, argv))
exit(EXIT_FAILURE);
-
-
+
/* start checking options and flags */
c = 0;
- if (fileopt->answer != NULL)
+ if (opt.file->answer != NULL)
c++;
- if (listopt->answers != NULL)
+ if (opt.list->answers != NULL)
c++;
- if (whereopt->answer != NULL)
+ if (opt.where->answer != NULL)
c++;
- if (nrandopt->answer != NULL)
+ if (opt.nrand->answer != NULL)
c++;
if (c > 1)
- G_fatal_error(_("List, file, where and random options are exclusive. "
- "Please specify only one of them"));
- c = 0;
-
- type_only = 0;
- if (!listopt->answers && !fileopt->answer && !whereopt->answer &&
- !nrandopt->answer) {
- type_only = 1;
+ G_fatal_error(_("Options <%s>, <%s>, <%s> and <%s> options are exclusive. "
+ "Please specify only one of them."),
+ opt.list->key, opt.file->key, opt.where->key,
+ opt.nrand->key);
+
+ type_only = FALSE;
+ if (!opt.list->answers && !opt.file->answer && !opt.where->answer &&
+ !opt.nrand->answer) {
+ type_only = TRUE;
}
- Vect_check_input_output_name(inopt->answer, outopt->answer,
+ input = opt.input->answer;
+ output = opt.output->answer;
+ Vect_check_input_output_name(input, output,
GV_FATAL_EXIT);
-
- /* set input vector map name and mapset */
- input = inopt->answer;
-
- /* set output vector map name */
- output = outopt->answer;
-
- if (d_flag->answer)
- dissolve = 1;
-
- if (!newopt->answer)
+
+ if (flag.d->answer)
+ dissolve = TRUE;
+ else
+ dissolve = FALSE;
+
+ if (!opt.new->answer)
new_cat = 0;
else
- new_cat = atoi(newopt->answer);
+ new_cat = atoi(opt.new->answer);
/* Do initial read of input file */
Vect_set_open_level(2); /* topology required */
- Vect_open_old2(&In, input, "", fieldopt->answer);
+ Vect_open_old2(&In, input, "", opt.field->answer);
- field = Vect_get_field_number(&In, fieldopt->answer);
+ field = Vect_get_field_number(&In, opt.field->answer);
- type = Vect_option_to_types(typopt);
+ type = Vect_option_to_types(opt.type);
if (type & GV_AREA) {
type |= GV_CENTROID;
}
/* Read categoy list */
cat_count = 0;
- if (listopt->answer != NULL) {
+ if (opt.list->answer != NULL) {
/* no file of categories to read, process cat list */
/* first check for valid list */
- for (i = 0; listopt->answers[i]; i++) {
- G_debug(2, "catlist item: %s", listopt->answers[i]);
- if (!scan_cats(listopt->answers[i], &x, &y))
+ for (i = 0; opt.list->answers[i]; i++) {
+ G_debug(2, "catlist item: %s", opt.list->answers[i]);
+ if (!scan_cats(opt.list->answers[i], &x, &y))
G_fatal_error(_("Category value in '%s' not valid"),
- listopt->answers[i]);
+ opt.list->answers[i]);
}
/* valid list, put into cat value array */
- for (i = 0; listopt->answers[i]; i++) {
- scan_cats(listopt->answers[i], &x, &y);
+ for (i = 0; opt.list->answers[i]; i++) {
+ scan_cats(opt.list->answers[i], &x, &y);
while (x <= y)
add_cat(x++);
}
}
- else if (fileopt->answer != NULL) { /* got a file of category numbers */
- if (G_strcasecmp(fileopt->answer, "-") == 0) {
+ else if (opt.file->answer != NULL) { /* got a file of category numbers */
+ if (strcmp(opt.file->answer, "-") == 0) {
in = stdin;
}
else {
- G_message(_("Process file <%s> for category numbers"),
- fileopt->answer);
+ G_verbose_message(_("Process file <%s> for category numbers..."),
+ opt.file->answer);
/* open input file */
- if ((in = fopen(fileopt->answer, "r")) == NULL)
+ if ((in = fopen(opt.file->answer, "r")) == NULL)
G_fatal_error(_("Unable to open specified file <%s>"),
- fileopt->answer);
+ opt.file->answer);
}
- while (1) {
+ while (TRUE) {
if (!fgets(buffr, 39, in))
break;
- G_chop(buffr); /* eliminate some white space, we accept numbers and dashes only */
+ /* eliminate some white space, we accept numbers and dashes only */
+ G_chop(buffr);
sscanf(buffr, "%[-0-9]", text);
if (strlen(text) == 0)
G_warning(_("Ignored text entry: %s"), buffr);
@@ -256,31 +242,30 @@
add_cat(x++);
}
- if (G_strcasecmp(fileopt->answer, "-") != 0)
+ if (strcmp(opt.file->answer, "-") != 0)
fclose(in);
-
}
- else if (whereopt->answer != NULL) {
+ else if (opt.where->answer != NULL) {
Fi = Vect_get_field(&In, field);
if (!Fi) {
G_fatal_error(_("Database connection not defined for layer <%s>"),
- fieldopt->answer);
+ opt.field->answer);
}
- G_debug(1, "Loading categories from table <%s>", Fi->table);
+ G_verbose_message(_("Loading categories from table <%s>..."), Fi->table);
driver = db_start_driver_open_database(Fi->driver, Fi->database);
if (driver == NULL)
G_fatal_error(_("Unable to open database <%s> by driver <%s>"),
Fi->database, Fi->driver);
- ncats = db_select_int(driver, Fi->table, Fi->key, whereopt->answer,
+ ncats = db_select_int(driver, Fi->table, Fi->key, opt.where->answer,
&cats);
if (ncats == -1)
- G_fatal_error(_("Unable select records from table <%s>"), Fi->table);
- G_message(_("%d categories loaded from table <%s>"), ncats,
- Fi->table);
-
+ G_fatal_error(_("Unable select records from table <%s>"),
+ Fi->table);
+ G_verbose_message(_("%d categories loaded"), ncats);
+
db_close_database(driver);
db_shutdown_driver(driver);
@@ -289,23 +274,23 @@
if (ncats >= 0)
G_free(cats);
}
- else if (nrandopt->answer != NULL) { /* Generate random category list */
-
+ else if (opt.nrand->answer != NULL) { /* Generate random category list */
/* We operate on layer's CAT's and thus valid layer is required */
if (Vect_cidx_get_field_index(&In, field) < 0)
G_fatal_error(_("This map has no categories attached. "
- "Use v.category to attach categories to this vector map."));
+ "Use v.category to attach categories to "
+ "this vector map."));
/* Don't do any processing, if user input is wrong */
- nrandom = atoi(nrandopt->answer);
+ nrandom = atoi(opt.nrand->answer);
if (nrandom < 1)
G_fatal_error(_("Please specify random number larger than 0"));
nfeatures = Vect_cidx_get_type_count(&In, field, type);
if (nrandom >= nfeatures)
G_fatal_error(_("Random category count must be smaller than feature count. "
- "There are only %d features of type(s): %s"),
- nfeatures, typopt->answer);
+ "There are only %d features of type(s): %s"),
+ nfeatures, opt.type->answer);
/* Let's create an array of uniq CAT values
According to Vlib/build.c, cidx should be allready sorted by dig_cidx_sort() */
@@ -326,14 +311,14 @@
}
if (nrandom >= ucat_count)
- G_fatal_error(_("Random category count is larger or equal to uniq \"%s\" feature category count %d"),
- typopt->answer, ucat_count);
+ G_fatal_error(_("Random category count is larger or equal to "
+ "uniq <%s> feature category count %d"),
+ opt.type->answer, ucat_count);
if (ucat_count >= RAND_MAX)
- G_fatal_error
- ("There are more categories than random number generator can reach. "
- "Report this as a GRASS bug.");
-
+ G_fatal_error(_("There are more categories than random number "
+ "generator can reach. Report this as a GRASS bug."));
+
seed = getpid();
/* Initialise random number generator */
G_math_rand(-1 * seed);
@@ -341,11 +326,11 @@
/* Fill cat_array with list of valid random numbers */
while (cat_count < nrandom) {
/* Random number in range from 0 to largest CAT value */
- prnd =
- (int)floor(G_math_rand(seed) *
- (ucat_array[ucat_count - 1] + 1));
+ prnd = (int) floor(G_math_rand(seed) *
+ (ucat_array[ucat_count - 1] + 1));
qsort(cat_array, cat_count, sizeof(int), cmp);
- /* Check if generated number isn't already in final list and is in list of existing CATs */
+ /* Check if generated number isn't already in
+ final list and is in list of existing CATs */
if (bsearch(&prnd, cat_array, cat_count, sizeof(int), cmp) == NULL
&& bsearch(&prnd, ucat_array, ucat_count, sizeof(int),
cmp) != NULL)
@@ -355,7 +340,6 @@
qsort(cat_array, cat_count, sizeof(int), cmp);
}
- /* Open output file only when it's required */
Vect_open_new(&Out, output, Vect_is_3d(&In));
Vect_hist_copy(&In, &Out);
Vect_hist_command(&Out);
@@ -364,116 +348,31 @@
Vect_copy_head_data(&In, &Out);
G_message(_("Extracting features..."));
- xtract_line(cat_count, cat_array, &In, &Out, new_cat, type, dissolve, field,
- type_only, r_flag->answer ? 1 : 0);
+
+ is_ogr = Vect_maptype(&Out) == GV_FORMAT_OGR_DIRECT;
+ if (!flag.t->answer && is_ogr) {
+ /* Copy attributes for OGR output */
+ if (!Fi)
+ Fi = Vect_get_field(&In, field);
+ if (!Fi)
+ G_fatal_error(_("Database connection not defined for layer <%s>"),
+ opt.field->answer);
+ Vect_map_add_dblink(&Out, Fi->number, Fi->name, Fi->table, Fi->key,
+ Fi->database, Fi->driver);
+ }
+ extract_line(cat_count, cat_array, &In, &Out, new_cat, type, dissolve, field,
+ type_only, flag.r->answer ? 1 : 0);
+
Vect_build(&Out);
/* Copy tables */
- if (!t_flag->answer) {
- int nlines, line;
- int ttype, ntabs = 0;
- struct field_info *IFi, *OFi;
-
- /* Collect list of output cats */
- Cats = Vect_new_cats_struct();
- nfields = Vect_cidx_get_num_fields(&Out);
- ocats = (int **)G_malloc(nfields * sizeof(int *));
- nocats = (int *)G_malloc(nfields * sizeof(int));
- fields = (int *)G_malloc(nfields * sizeof(int));
- for (i = 0; i < nfields; i++) {
- nocats[i] = 0;
- ocats[i] =
- (int *)G_malloc(Vect_cidx_get_num_cats_by_index(&Out, i) *
- sizeof(int));
- fields[i] = Vect_cidx_get_field_number(&Out, i);
- }
-
- nlines = Vect_get_num_lines(&Out);
- for (line = 1; line <= nlines; line++) {
- Vect_read_line(&Out, NULL, Cats, line);
-
- for (i = 0; i < Cats->n_cats; i++) {
- int f, j;
-
- for (j = 0; j < nfields; j++) { /* find field */
- if (fields[j] == Cats->field[i]) {
- f = j;
- break;
- }
- }
- ocats[f][nocats[f]] = Cats->cat[i];
- nocats[f]++;
- }
- }
-
- /* Copy tables */
- G_message(_("Writing attributes..."));
-
- /* Number of output tabs */
- for (i = 0; i < Vect_get_num_dblinks(&In); i++) {
- int j, f = -1;
-
- IFi = Vect_get_dblink(&In, i);
-
- for (j = 0; j < nfields; j++) { /* find field */
- if (fields[j] == IFi->number) {
- f = j;
- break;
- }
- }
- if (f >= 0 && nocats[f] > 0)
- ntabs++;
- }
-
- if (ntabs > 1)
- ttype = GV_MTABLE;
- else
- ttype = GV_1TABLE;
-
- for (i = 0; i < nfields; i++) {
- int ret;
-
- if (fields[i] == 0)
- continue;
- if (nocats[i] == 0)
- continue;
- if (fields[i] == atoi(fieldopt->answer) && new_cat != -1)
- continue;
-
- G_verbose_message(_("Layer %d"), fields[i]);
-
- /* Make a list of categories */
- IFi = Vect_get_field(&In, fields[i]);
- if (!IFi) { /* no table */
- G_verbose_message(_("No table"));
- continue;
- }
-
- OFi =
- Vect_default_field_info(&Out, IFi->number, IFi->name, ttype);
-
- ret =
- db_copy_table_by_ints(IFi->driver, IFi->database, IFi->table,
- OFi->driver,
- Vect_subst_var(OFi->database, &Out),
- OFi->table, IFi->key, ocats[i],
- nocats[i]);
-
- if (ret == DB_FAILED) {
- G_warning(_("Unable to copy table"));
- }
- else {
- Vect_map_add_dblink(&Out, OFi->number, OFi->name, OFi->table,
- IFi->key, OFi->database, OFi->driver);
- }
- G_done_msg(" ");
- }
+ if (!flag.t->answer && !is_ogr) {
+ copy_tabs(&In, field, new_cat, &Out);
}
-
+
Vect_close(&In);
-
-
+
/* remove duplicate centroids */
if (dissolve) {
int line, nlines, ltype, area;
@@ -497,14 +396,24 @@
Vect_build_partial(&Out, GV_BUILD_NONE);
Vect_build(&Out);
}
-
+
Vect_close(&Out);
-
+
exit(EXIT_SUCCESS);
}
+void add_cat(int x)
+{
+ G_debug(2, "add_cat %d", x);
+ if (cat_count >= cat_size) {
+ cat_size = (cat_size < 1000) ? 1000 : cat_size * 2;
+ cat_array = G_realloc(cat_array, cat_size * sizeof(int));
+ }
+ cat_array[cat_count++] = x;
+}
+
int scan_cats(char *s, int *x, int *y)
{
char dummy[2];
More information about the grass-commit
mailing list